blob: c44ce9195a42a8e415c8a415c020d81b8668597e [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
19PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000020"This module provides access to operating system functionality that is\n\
21standardized by the C Standard and the POSIX standard (a thinly\n\
22disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000024
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000025#if defined(PYOS_OS2)
26#define INCL_DOS
27#define INCL_DOSERRORS
28#define INCL_DOSPROCESS
29#define INCL_NOPMAPI
30#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000031#if defined(PYCC_GCC)
32#include <ctype.h>
33#include <io.h>
34#include <stdio.h>
35#include <process.h>
36#include "osdefs.h"
37#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000038#endif
39
Guido van Rossumb6775db1994-08-01 11:34:53 +000040#include <sys/types.h>
41#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000042
Guido van Rossum36bc6801995-06-14 22:54:23 +000043#ifdef HAVE_SYS_WAIT_H
44#include <sys/wait.h> /* For WNOHANG */
45#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000046
Guido van Rossuma376cc51996-12-05 23:43:35 +000047#ifdef HAVE_SIGNAL_H
48#include <signal.h>
49#endif
50
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#ifdef HAVE_FCNTL_H
52#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000053#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000054
Guido van Rossuma6535fd2001-10-18 19:44:10 +000055#ifdef HAVE_GRP_H
56#include <grp.h>
57#endif
58
Guido van Rossuma4916fa1996-05-23 22:58:55 +000059/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000060/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000062#include <process.h>
63#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000064#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000065#define HAVE_GETCWD 1
66#define HAVE_OPENDIR 1
67#define HAVE_SYSTEM 1
68#if defined(__OS2__)
69#define HAVE_EXECV 1
70#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000071#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072#include <process.h>
73#else
74#ifdef __BORLANDC__ /* Borland compiler */
75#define HAVE_EXECV 1
76#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#define HAVE_OPENDIR 1
78#define HAVE_PIPE 1
79#define HAVE_POPEN 1
80#define HAVE_SYSTEM 1
81#define HAVE_WAIT 1
82#else
83#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000084#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +000085#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000086#define HAVE_EXECV 1
87#define HAVE_PIPE 1
88#define HAVE_POPEN 1
89#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000090#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000091#else
92#if defined(PYOS_OS2) && defined(PYCC_GCC)
93/* Everything needed is defined in PC/os2emx/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#else /* all other compilers */
95/* Unix functions that the configure script doesn't check for */
96#define HAVE_EXECV 1
97#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000098#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
99#define HAVE_FORK1 1
100#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_GETCWD 1
102#define HAVE_GETEGID 1
103#define HAVE_GETEUID 1
104#define HAVE_GETGID 1
105#define HAVE_GETPPID 1
106#define HAVE_GETUID 1
107#define HAVE_KILL 1
108#define HAVE_OPENDIR 1
109#define HAVE_PIPE 1
110#define HAVE_POPEN 1
111#define HAVE_SYSTEM 1
112#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000113#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000114#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#endif /* _MSC_VER */
116#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000117#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000118#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000119
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000121
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000122#if defined(sun) && !defined(__SVR4)
123/* SunOS 4.1.4 doesn't have prototypes for these: */
124extern int rename(const char *, const char *);
125extern int pclose(FILE *);
126extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000127extern int fsync(int);
128extern int lstat(const char *, struct stat *);
129extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000130#endif
131
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000132#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000135#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000136#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000138#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000139extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#endif
142#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int chdir(char *);
144extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000145#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(const char *);
147extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000149#ifdef __BORLANDC__
150extern int chmod(const char *, int);
151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000153#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int chown(const char *, uid_t, gid_t);
155extern char *getcwd(char *, int);
156extern char *strerror(int);
157extern int link(const char *, const char *);
158extern int rename(const char *, const char *);
159extern int stat(const char *, struct stat *);
160extern int unlink(const char *);
161extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000164#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000167#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000169
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172#ifdef HAVE_UTIME_H
173#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000174#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000176#ifdef HAVE_SYS_UTIME_H
177#include <sys/utime.h>
178#define HAVE_UTIME_H /* pretend we do for the rest of this file */
179#endif /* HAVE_SYS_UTIME_H */
180
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181#ifdef HAVE_SYS_TIMES_H
182#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000183#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184
185#ifdef HAVE_SYS_PARAM_H
186#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000187#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000188
189#ifdef HAVE_SYS_UTSNAME_H
190#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000191#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000193#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000195#define NAMLEN(dirent) strlen((dirent)->d_name)
196#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000197#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#include <direct.h>
199#define NAMLEN(dirent) strlen((dirent)->d_name)
200#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000202#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#endif
207#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#include <direct.h>
217#include <io.h>
218#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000219#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000220#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000222#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000224#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossumd48f2521997-12-05 22:19:34 +0000227#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230
Tim Petersbc2e10e2002-03-03 23:17:02 +0000231#ifndef MAXPATHLEN
232#define MAXPATHLEN 1024
233#endif /* MAXPATHLEN */
234
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000235#ifdef UNION_WAIT
236/* Emulate some macros on systems that have a union instead of macros */
237
238#ifndef WIFEXITED
239#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
240#endif
241
242#ifndef WEXITSTATUS
243#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
244#endif
245
246#ifndef WTERMSIG
247#define WTERMSIG(u_wait) ((u_wait).w_termsig)
248#endif
249
250#endif /* UNION_WAIT */
251
Greg Wardb48bc172000-03-01 21:51:56 +0000252/* Don't use the "_r" form if we don't need it (also, won't have a
253 prototype for it, at least on Solaris -- maybe others as well?). */
254#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
255#define USE_CTERMID_R
256#endif
257
258#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
259#define USE_TMPNAM_R
260#endif
261
Fred Drake699f3522000-06-29 21:12:41 +0000262/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000263#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000264#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000265# define STAT _stati64
266# define FSTAT _fstati64
267# define STRUCT_STAT struct _stati64
268#else
269# define STAT stat
270# define FSTAT fstat
271# define STRUCT_STAT struct stat
272#endif
273
Neal Norwitz3d949422002-04-20 13:46:43 +0000274#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
275#include <sys/mkdev.h>
276#endif
Fred Drake699f3522000-06-29 21:12:41 +0000277
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278/* Return a dictionary corresponding to the POSIX environment table */
279
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000280#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283
Barry Warsaw53699e91996-12-10 23:23:01 +0000284static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000285convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286{
Barry Warsaw53699e91996-12-10 23:23:01 +0000287 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000289 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 if (d == NULL)
291 return NULL;
292 if (environ == NULL)
293 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000294 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000296 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000297 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298 char *p = strchr(*e, '=');
299 if (p == NULL)
300 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000301 k = PyString_FromStringAndSize(*e, (int)(p-*e));
302 if (k == NULL) {
303 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000305 }
306 v = PyString_FromString(p+1);
307 if (v == NULL) {
308 PyErr_Clear();
309 Py_DECREF(k);
310 continue;
311 }
312 if (PyDict_GetItem(d, k) == NULL) {
313 if (PyDict_SetItem(d, k, v) != 0)
314 PyErr_Clear();
315 }
316 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000317 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000319#if defined(PYOS_OS2)
320 {
321 APIRET rc;
322 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
323
324 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000325 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000326 PyObject *v = PyString_FromString(buffer);
327 PyDict_SetItemString(d, "BEGINLIBPATH", v);
328 Py_DECREF(v);
329 }
330 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
331 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
332 PyObject *v = PyString_FromString(buffer);
333 PyDict_SetItemString(d, "ENDLIBPATH", v);
334 Py_DECREF(v);
335 }
336 }
337#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338 return d;
339}
340
341
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000342/* Set a POSIX-specific error from errno, and return NULL */
343
Barry Warsawd58d7641998-07-23 16:14:40 +0000344static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000345posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000346{
Barry Warsawca74da41999-02-09 19:31:45 +0000347 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348}
Barry Warsawd58d7641998-07-23 16:14:40 +0000349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000350posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000351{
Barry Warsawca74da41999-02-09 19:31:45 +0000352 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000353}
354
Mark Hammondef8b6542001-05-13 08:04:26 +0000355static PyObject *
356posix_error_with_allocated_filename(char* name)
357{
358 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
359 PyMem_Free(name);
360 return rc;
361}
362
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000363#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000364static PyObject *
365win32_error(char* function, char* filename)
366{
Mark Hammond33a6da92000-08-15 00:46:38 +0000367 /* XXX We should pass the function name along in the future.
368 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000369 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000370 Windows error object, which is non-trivial.
371 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000372 errno = GetLastError();
373 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000374 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000375 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000376 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000377}
378#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379
Guido van Rossumd48f2521997-12-05 22:19:34 +0000380#if defined(PYOS_OS2)
381/**********************************************************************
382 * Helper Function to Trim and Format OS/2 Messages
383 **********************************************************************/
384 static void
385os2_formatmsg(char *msgbuf, int msglen, char *reason)
386{
387 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
388
389 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
390 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
391
392 while (lastc > msgbuf && isspace(*lastc))
393 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
394 }
395
396 /* Add Optional Reason Text */
397 if (reason) {
398 strcat(msgbuf, " : ");
399 strcat(msgbuf, reason);
400 }
401}
402
403/**********************************************************************
404 * Decode an OS/2 Operating System Error Code
405 *
406 * A convenience function to lookup an OS/2 error code and return a
407 * text message we can use to raise a Python exception.
408 *
409 * Notes:
410 * The messages for errors returned from the OS/2 kernel reside in
411 * the file OSO001.MSG in the \OS2 directory hierarchy.
412 *
413 **********************************************************************/
414 static char *
415os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
416{
417 APIRET rc;
418 ULONG msglen;
419
420 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
421 Py_BEGIN_ALLOW_THREADS
422 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
423 errorcode, "oso001.msg", &msglen);
424 Py_END_ALLOW_THREADS
425
426 if (rc == NO_ERROR)
427 os2_formatmsg(msgbuf, msglen, reason);
428 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000429 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000430 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000431
432 return msgbuf;
433}
434
435/* Set an OS/2-specific error and return NULL. OS/2 kernel
436 errors are not in a global variable e.g. 'errno' nor are
437 they congruent with posix error numbers. */
438
439static PyObject * os2_error(int code)
440{
441 char text[1024];
442 PyObject *v;
443
444 os2_strerror(text, sizeof(text), code, "");
445
446 v = Py_BuildValue("(is)", code, text);
447 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000448 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000449 Py_DECREF(v);
450 }
451 return NULL; /* Signal to Python that an Exception is Pending */
452}
453
454#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455
456/* POSIX generic methods */
457
Barry Warsaw53699e91996-12-10 23:23:01 +0000458static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000459posix_fildes(PyObject *fdobj, int (*func)(int))
460{
461 int fd;
462 int res;
463 fd = PyObject_AsFileDescriptor(fdobj);
464 if (fd < 0)
465 return NULL;
466 Py_BEGIN_ALLOW_THREADS
467 res = (*func)(fd);
468 Py_END_ALLOW_THREADS
469 if (res < 0)
470 return posix_error();
471 Py_INCREF(Py_None);
472 return Py_None;
473}
Guido van Rossum21142a01999-01-08 21:05:37 +0000474
475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000476posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000477{
Mark Hammondef8b6542001-05-13 08:04:26 +0000478 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000479 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000480 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000481 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000483 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000484 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000485 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000486 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000487 return posix_error_with_allocated_filename(path1);
488 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000489 Py_INCREF(Py_None);
490 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000491}
492
Barry Warsaw53699e91996-12-10 23:23:01 +0000493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000494posix_2str(PyObject *args, char *format,
495 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000496{
Mark Hammondef8b6542001-05-13 08:04:26 +0000497 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000498 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000499 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000500 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000501 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000503 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000504 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000505 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000506 PyMem_Free(path1);
507 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000508 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000509 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000510 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000511 Py_INCREF(Py_None);
512 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000513}
514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000515PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000516"stat_result: Result from stat or lstat.\n\n\
517This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000518 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000519or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
520\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000521Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000522they are available as attributes only.\n\
523\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000525
526static PyStructSequence_Field stat_result_fields[] = {
527 {"st_mode", "protection bits"},
528 {"st_ino", "inode"},
529 {"st_dev", "device"},
530 {"st_nlink", "number of hard links"},
531 {"st_uid", "user ID of owner"},
532 {"st_gid", "group ID of owner"},
533 {"st_size", "total size, in bytes"},
534 {"st_atime", "time of last access"},
535 {"st_mtime", "time of last modification"},
536 {"st_ctime", "time of last change"},
537#ifdef HAVE_ST_BLKSIZE
538 {"st_blksize", "blocksize for filesystem I/O"},
539#endif
540#ifdef HAVE_ST_BLOCKS
541 {"st_blocks", "number of blocks allocated"},
542#endif
543#ifdef HAVE_ST_RDEV
544 {"st_rdev", "device type (if inode device)"},
545#endif
546 {0}
547};
548
549#ifdef HAVE_ST_BLKSIZE
550#define ST_BLKSIZE_IDX 10
551#else
552#define ST_BLKSIZE_IDX 9
553#endif
554
555#ifdef HAVE_ST_BLOCKS
556#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
557#else
558#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
559#endif
560
561#ifdef HAVE_ST_RDEV
562#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
563#else
564#define ST_RDEV_IDX ST_BLOCKS_IDX
565#endif
566
567static PyStructSequence_Desc stat_result_desc = {
568 "stat_result", /* name */
569 stat_result__doc__, /* doc */
570 stat_result_fields,
571 10
572};
573
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000574PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000575"statvfs_result: Result from statvfs or fstatvfs.\n\n\
576This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000577 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000578or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000579\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000580See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000581
582static PyStructSequence_Field statvfs_result_fields[] = {
583 {"f_bsize", },
584 {"f_frsize", },
585 {"f_blocks", },
586 {"f_bfree", },
587 {"f_bavail", },
588 {"f_files", },
589 {"f_ffree", },
590 {"f_favail", },
591 {"f_flag", },
592 {"f_namemax",},
593 {0}
594};
595
596static PyStructSequence_Desc statvfs_result_desc = {
597 "statvfs_result", /* name */
598 statvfs_result__doc__, /* doc */
599 statvfs_result_fields,
600 10
601};
602
603static PyTypeObject StatResultType;
604static PyTypeObject StatVFSResultType;
605
Tim Peters5aa91602002-01-30 05:46:57 +0000606/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000607 (used by posix_stat() and posix_fstat()) */
608static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000609_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000610{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000611 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000612 if (v == NULL)
613 return NULL;
614
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000615 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000616#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000617 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000618 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000619#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000620 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000621#endif
622#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000623 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000624 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000625#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000626 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000627#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000628 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
629 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
630 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000631#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000632 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000633 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000634#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000635 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000636#endif
637#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000638 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000639 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000640 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000641 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000642 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000643 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000644#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000645 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
646 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
647 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
648#endif
649
650#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000651 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000652 PyInt_FromLong((long)st.st_blksize));
653#endif
654#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000655 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000656 PyInt_FromLong((long)st.st_blocks));
657#endif
658#ifdef HAVE_ST_RDEV
659 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
660 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000661#endif
662
663 if (PyErr_Occurred()) {
664 Py_DECREF(v);
665 return NULL;
666 }
667
668 return v;
669}
670
Barry Warsaw53699e91996-12-10 23:23:01 +0000671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000672posix_do_stat(PyObject *self, PyObject *args, char *format,
673 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000674{
Fred Drake699f3522000-06-29 21:12:41 +0000675 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000676 char *path = NULL; /* pass this to stat; do not free() it */
677 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000678 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000679
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000680#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000681 int pathlen;
682 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000683#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000684
Tim Peters5aa91602002-01-30 05:46:57 +0000685 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000686 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000687 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000688 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000689
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000690#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000691 pathlen = strlen(path);
692 /* the library call can blow up if the file name is too long! */
693 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000694 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000695 errno = ENAMETOOLONG;
696 return posix_error();
697 }
698
Tim Peters500bd032001-12-19 19:05:01 +0000699 /* Remove trailing slash or backslash, unless it's the current
700 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
701 */
702 if (pathlen > 0 &&
703 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
704 /* It does end with a slash -- exempt the root drive cases. */
705 /* XXX UNC root drives should also be exempted? */
706 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
707 /* leave it alone */;
708 else {
709 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000710 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000711 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000712 path = pathcopy;
713 }
714 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000715#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000716
Barry Warsaw53699e91996-12-10 23:23:01 +0000717 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000718 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000719 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000720 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000721 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000722
Tim Peters500bd032001-12-19 19:05:01 +0000723 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000724 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725}
726
727
728/* POSIX methods */
729
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000730PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000731"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000732Use the real uid/gid to test for access to a path. Note that most\n\
733operations will use the effective uid/gid, therefore this routine can\n\
734be used in a suid/sgid environment to test if the invoking user has the\n\
735specified access to the path. The mode argument can be F_OK to test\n\
736existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000737
738static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000739posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000740{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000741 char *path;
742 int mode;
743 int res;
744
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000745 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000746 return NULL;
747 Py_BEGIN_ALLOW_THREADS
748 res = access(path, mode);
749 Py_END_ALLOW_THREADS
750 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000751}
752
Guido van Rossumd371ff11999-01-25 16:12:23 +0000753#ifndef F_OK
754#define F_OK 0
755#endif
756#ifndef R_OK
757#define R_OK 4
758#endif
759#ifndef W_OK
760#define W_OK 2
761#endif
762#ifndef X_OK
763#define X_OK 1
764#endif
765
766#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000767PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000768"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000769Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000770
771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000772posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000773{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000774 int id;
775 char *ret;
776
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000777 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000778 return NULL;
779
Guido van Rossum94f6f721999-01-06 18:42:14 +0000780 ret = ttyname(id);
781 if (ret == NULL)
782 return(posix_error());
783 return(PyString_FromString(ret));
784}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000785#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000786
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000787#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000788PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000789"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000790Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000791
792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000793posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000794{
795 char *ret;
796 char buffer[L_ctermid];
797
798 if (!PyArg_ParseTuple(args, ":ctermid"))
799 return NULL;
800
Greg Wardb48bc172000-03-01 21:51:56 +0000801#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000802 ret = ctermid_r(buffer);
803#else
804 ret = ctermid(buffer);
805#endif
806 if (ret == NULL)
807 return(posix_error());
808 return(PyString_FromString(buffer));
809}
810#endif
811
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000812PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000813"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000814Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000815
Barry Warsaw53699e91996-12-10 23:23:01 +0000816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000817posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000819#if defined(PYOS_OS2) && defined(PYCC_GCC)
820 return posix_1str(args, "et:chdir", _chdir2);
821#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000822 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000823#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824}
825
Fred Drake4d1e64b2002-04-15 19:40:07 +0000826#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000827PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000828"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +0000829Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000830opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +0000831
832static PyObject *
833posix_fchdir(PyObject *self, PyObject *fdobj)
834{
835 return posix_fildes(fdobj, fchdir);
836}
837#endif /* HAVE_FCHDIR */
838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000839
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000840PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000841"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000842Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000843
Barry Warsaw53699e91996-12-10 23:23:01 +0000844static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000845posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846{
Mark Hammondef8b6542001-05-13 08:04:26 +0000847 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000848 int i;
849 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000850 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000851 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000852 return NULL;
853 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000854 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000855 Py_END_ALLOW_THREADS
856 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000857 return posix_error_with_allocated_filename(path);
858 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000859 Py_INCREF(Py_None);
860 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000861}
862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000863
Martin v. Löwis244edc82001-10-04 22:44:26 +0000864#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000865PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000866"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000867Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +0000868
869static PyObject *
870posix_chroot(PyObject *self, PyObject *args)
871{
872 return posix_1str(args, "et:chroot", chroot);
873}
874#endif
875
Guido van Rossum21142a01999-01-08 21:05:37 +0000876#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000877PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000878"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000879force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000880
881static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000882posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000883{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000884 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000885}
886#endif /* HAVE_FSYNC */
887
888#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000889
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000890#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000891extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
892#endif
893
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000894PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000895"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +0000896force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000897 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000898
899static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000900posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000901{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000902 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000903}
904#endif /* HAVE_FDATASYNC */
905
906
Fredrik Lundh10723342000-07-10 16:38:09 +0000907#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000908PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000909"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000910Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000911
Barry Warsaw53699e91996-12-10 23:23:01 +0000912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000913posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000914{
Mark Hammondef8b6542001-05-13 08:04:26 +0000915 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000916 int uid, gid;
917 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000918 if (!PyArg_ParseTuple(args, "etii:chown",
919 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000920 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000921 return NULL;
922 Py_BEGIN_ALLOW_THREADS
923 res = chown(path, (uid_t) uid, (gid_t) gid);
924 Py_END_ALLOW_THREADS
925 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000926 return posix_error_with_allocated_filename(path);
927 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000928 Py_INCREF(Py_None);
929 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000930}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000931#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000932
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +0000933#ifdef HAVE_LCHOWN
934PyDoc_STRVAR(posix_lchown__doc__,
935"lchown(path, uid, gid)\n\n\
936Change the owner and group id of path to the numeric uid and gid.\n\
937This function will not follow symbolic links.");
938
939static PyObject *
940posix_lchown(PyObject *self, PyObject *args)
941{
942 char *path = NULL;
943 int uid, gid;
944 int res;
945 if (!PyArg_ParseTuple(args, "etii:lchown",
946 Py_FileSystemDefaultEncoding, &path,
947 &uid, &gid))
948 return NULL;
949 Py_BEGIN_ALLOW_THREADS
950 res = lchown(path, (uid_t) uid, (gid_t) gid);
951 Py_END_ALLOW_THREADS
952 if (res < 0)
953 return posix_error_with_allocated_filename(path);
954 PyMem_Free(path);
955 Py_INCREF(Py_None);
956 return Py_None;
957}
958#endif /* HAVE_LCHOWN */
959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000960
Guido van Rossum36bc6801995-06-14 22:54:23 +0000961#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000962PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000963"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000964Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000965
Barry Warsaw53699e91996-12-10 23:23:01 +0000966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000967posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000968{
969 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000970 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000971 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000972 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000973 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000974#if defined(PYOS_OS2) && defined(PYCC_GCC)
975 res = _getcwd2(buf, sizeof buf);
976#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000977 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000978#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000979 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000980 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000981 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000982 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000983}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000984#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000986
Guido van Rossumb6775db1994-08-01 11:34:53 +0000987#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000988PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000989"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000990Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000991
Barry Warsaw53699e91996-12-10 23:23:01 +0000992static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000993posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000994{
Mark Hammondef8b6542001-05-13 08:04:26 +0000995 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000996}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000997#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000999
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001000PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001001"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001002Return a list containing the names of the entries in the directory.\n\
1003\n\
1004 path: path of directory to list\n\
1005\n\
1006The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001007entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001008
Barry Warsaw53699e91996-12-10 23:23:01 +00001009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001010posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001011{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001012 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001013 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001014#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001015
Barry Warsaw53699e91996-12-10 23:23:01 +00001016 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001017 HANDLE hFindFile;
1018 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001019 /* MAX_PATH characters could mean a bigger encoded string */
1020 char namebuf[MAX_PATH*2+5];
1021 char *bufptr = namebuf;
1022 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001023
Tim Peters5aa91602002-01-30 05:46:57 +00001024 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001025 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001026 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001027 if (len > 0) {
1028 char ch = namebuf[len-1];
1029 if (ch != SEP && ch != ALTSEP && ch != ':')
1030 namebuf[len++] = '/';
1031 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001032 strcpy(namebuf + len, "*.*");
1033
Barry Warsaw53699e91996-12-10 23:23:01 +00001034 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001035 return NULL;
1036
1037 hFindFile = FindFirstFile(namebuf, &FileData);
1038 if (hFindFile == INVALID_HANDLE_VALUE) {
1039 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001040 if (errno == ERROR_FILE_NOT_FOUND)
1041 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001042 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001043 }
1044 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001045 if (FileData.cFileName[0] == '.' &&
1046 (FileData.cFileName[1] == '\0' ||
1047 FileData.cFileName[1] == '.' &&
1048 FileData.cFileName[2] == '\0'))
1049 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001050 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001051 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001052 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001053 d = NULL;
1054 break;
1055 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001056 if (PyList_Append(d, v) != 0) {
1057 Py_DECREF(v);
1058 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001059 d = NULL;
1060 break;
1061 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001062 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001063 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1064
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001065 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001066 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001067
1068 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001069
Tim Peters0bb44a42000-09-15 07:44:49 +00001070#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001071
1072#ifndef MAX_PATH
1073#define MAX_PATH CCHMAXPATH
1074#endif
1075 char *name, *pt;
1076 int len;
1077 PyObject *d, *v;
1078 char namebuf[MAX_PATH+5];
1079 HDIR hdir = 1;
1080 ULONG srchcnt = 1;
1081 FILEFINDBUF3 ep;
1082 APIRET rc;
1083
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001084 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001085 return NULL;
1086 if (len >= MAX_PATH) {
1087 PyErr_SetString(PyExc_ValueError, "path too long");
1088 return NULL;
1089 }
1090 strcpy(namebuf, name);
1091 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001092 if (*pt == ALTSEP)
1093 *pt = SEP;
1094 if (namebuf[len-1] != SEP)
1095 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001096 strcpy(namebuf + len, "*.*");
1097
1098 if ((d = PyList_New(0)) == NULL)
1099 return NULL;
1100
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001101 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1102 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001103 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001104 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1105 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1106 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001107
1108 if (rc != NO_ERROR) {
1109 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001110 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001111 }
1112
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001113 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001114 do {
1115 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001116 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001117 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001118
1119 strcpy(namebuf, ep.achName);
1120
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001121 /* Leave Case of Name Alone -- In Native Form */
1122 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001123
1124 v = PyString_FromString(namebuf);
1125 if (v == NULL) {
1126 Py_DECREF(d);
1127 d = NULL;
1128 break;
1129 }
1130 if (PyList_Append(d, v) != 0) {
1131 Py_DECREF(v);
1132 Py_DECREF(d);
1133 d = NULL;
1134 break;
1135 }
1136 Py_DECREF(v);
1137 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1138 }
1139
1140 return d;
1141#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001142
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001143 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001144 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001145 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001146 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001147 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001148 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001149 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001150 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001151 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001152 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153 closedir(dirp);
1154 return NULL;
1155 }
1156 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001157 if (ep->d_name[0] == '.' &&
1158 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001159 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001160 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001161 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001163 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001164 d = NULL;
1165 break;
1166 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001167 if (PyList_Append(d, v) != 0) {
1168 Py_DECREF(v);
1169 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001170 d = NULL;
1171 break;
1172 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001173 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001174 }
1175 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001176
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001177 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001178
Tim Peters0bb44a42000-09-15 07:44:49 +00001179#endif /* which OS */
1180} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001181
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001182#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001183/* A helper function for abspath on win32 */
1184static PyObject *
1185posix__getfullpathname(PyObject *self, PyObject *args)
1186{
1187 /* assume encoded strings wont more than double no of chars */
1188 char inbuf[MAX_PATH*2];
1189 char *inbufp = inbuf;
1190 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1191 char outbuf[MAX_PATH*2];
1192 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001193 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1194 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001195 &insize))
1196 return NULL;
1197 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1198 outbuf, &temp))
1199 return win32_error("GetFullPathName", inbuf);
1200 return PyString_FromString(outbuf);
1201} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001202#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001203
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001204PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001205"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001206Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001207
Barry Warsaw53699e91996-12-10 23:23:01 +00001208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001209posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001210{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001211 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001212 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001213 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001214 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001215 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001216 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001217 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001218#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001219 res = mkdir(path);
1220#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001221 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001222#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001223 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001224 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001225 return posix_error_with_allocated_filename(path);
1226 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001227 Py_INCREF(Py_None);
1228 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001229}
1230
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001231
Guido van Rossumb6775db1994-08-01 11:34:53 +00001232#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001233#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1234#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1235#include <sys/resource.h>
1236#endif
1237#endif
1238
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001239PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001240"nice(inc) -> new_priority\n\n\
1241Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001242
Barry Warsaw53699e91996-12-10 23:23:01 +00001243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001244posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001245{
1246 int increment, value;
1247
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001248 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001249 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001250
1251 /* There are two flavours of 'nice': one that returns the new
1252 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001253 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1254 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001255
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001256 If we are of the nice family that returns the new priority, we
1257 need to clear errno before the call, and check if errno is filled
1258 before calling posix_error() on a returnvalue of -1, because the
1259 -1 may be the actual new priority! */
1260
1261 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001262 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001263#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001264 if (value == 0)
1265 value = getpriority(PRIO_PROCESS, 0);
1266#endif
1267 if (value == -1 && errno != 0)
1268 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001269 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001270 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001271}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001272#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001274
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001275PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001276"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001277Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001278
Barry Warsaw53699e91996-12-10 23:23:01 +00001279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001280posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001281{
Mark Hammondef8b6542001-05-13 08:04:26 +00001282 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001283}
1284
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001285
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001286PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001287"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001288Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001289
Barry Warsaw53699e91996-12-10 23:23:01 +00001290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001291posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292{
Mark Hammondef8b6542001-05-13 08:04:26 +00001293 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001294}
1295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001296
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001297PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001298"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001299Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001300
Barry Warsaw53699e91996-12-10 23:23:01 +00001301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001302posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303{
Mark Hammondef8b6542001-05-13 08:04:26 +00001304 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305}
1306
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001307
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001308#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001309PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001310"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001311Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001312
Barry Warsaw53699e91996-12-10 23:23:01 +00001313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001314posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001315{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001316 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001317 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001318 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001319 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001320 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001321 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001322 Py_END_ALLOW_THREADS
1323 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001324}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001325#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001327
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001328PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001329"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001330Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001331
Barry Warsaw53699e91996-12-10 23:23:01 +00001332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001333posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001334{
1335 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001336 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001337 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001338 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001339 if (i < 0)
1340 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001341 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342}
1343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001345PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001346"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001347Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001348
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001349PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001350"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001351Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001352
Barry Warsaw53699e91996-12-10 23:23:01 +00001353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001354posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001355{
Mark Hammondef8b6542001-05-13 08:04:26 +00001356 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357}
1358
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001359
Guido van Rossumb6775db1994-08-01 11:34:53 +00001360#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001361PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001362"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001363Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001364
Barry Warsaw53699e91996-12-10 23:23:01 +00001365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001366posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001367{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001368 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001369 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001370 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001371 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001372 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001373 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001374 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001375 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001376 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001377 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001378 u.sysname,
1379 u.nodename,
1380 u.release,
1381 u.version,
1382 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001383}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001384#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001385
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001386
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001387PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001388"utime(path, (atime, utime))\n\
1389utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001390Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001391second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001392
Barry Warsaw53699e91996-12-10 23:23:01 +00001393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001394posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001395{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001396 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001397 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001398 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001399 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001400
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001401/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001402#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001403 struct utimbuf buf;
1404#define ATIME buf.actime
1405#define MTIME buf.modtime
1406#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001407#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001408 time_t buf[2];
1409#define ATIME buf[0]
1410#define MTIME buf[1]
1411#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001412#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001413
Barry Warsaw3cef8562000-05-01 16:17:24 +00001414 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001415 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001416 if (arg == Py_None) {
1417 /* optional time values not given */
1418 Py_BEGIN_ALLOW_THREADS
1419 res = utime(path, NULL);
1420 Py_END_ALLOW_THREADS
1421 }
Neal Norwitz50584b42002-07-30 01:23:07 +00001422 else if (!PyArg_ParseTuple(arg, "ll", &atime, &mtime)) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001423 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001424 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001425 return NULL;
1426 }
1427 else {
1428 ATIME = atime;
1429 MTIME = mtime;
1430 Py_BEGIN_ALLOW_THREADS
1431 res = utime(path, UTIME_ARG);
1432 Py_END_ALLOW_THREADS
1433 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001434 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001435 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001436 Py_INCREF(Py_None);
1437 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001438#undef UTIME_ARG
1439#undef ATIME
1440#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001441}
1442
Guido van Rossum85e3b011991-06-03 12:42:10 +00001443
Guido van Rossum3b066191991-06-04 19:40:25 +00001444/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001445
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001446PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001447"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001448Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001449
Barry Warsaw53699e91996-12-10 23:23:01 +00001450static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001451posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001452{
1453 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001454 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001455 return NULL;
1456 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001457 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001458}
1459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001460
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001461#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001462PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001463"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001464Execute an executable path with arguments, replacing current process.\n\
1465\n\
1466 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001467 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001468
Barry Warsaw53699e91996-12-10 23:23:01 +00001469static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001470posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001471{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001472 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001473 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001474 char **argvlist;
1475 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001476 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001477
Guido van Rossum89b33251993-10-22 14:26:06 +00001478 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001479 argv is a list or tuple of strings. */
1480
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001481 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001482 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001483 if (PyList_Check(argv)) {
1484 argc = PyList_Size(argv);
1485 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001486 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001487 else if (PyTuple_Check(argv)) {
1488 argc = PyTuple_Size(argv);
1489 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001490 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001491 else {
Fred Drake661ea262000-10-24 19:57:45 +00001492 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001493 return NULL;
1494 }
1495
1496 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001497 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001498 return NULL;
1499 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001500
Barry Warsaw53699e91996-12-10 23:23:01 +00001501 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001502 if (argvlist == NULL)
1503 return NULL;
1504 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001505 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1506 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001507 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001508 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001509 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001510
Guido van Rossum85e3b011991-06-03 12:42:10 +00001511 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001512 }
1513 argvlist[argc] = NULL;
1514
Guido van Rossumb6775db1994-08-01 11:34:53 +00001515#ifdef BAD_EXEC_PROTOTYPES
1516 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001517#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001518 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001519#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001520
Guido van Rossum85e3b011991-06-03 12:42:10 +00001521 /* If we get here it's definitely an error */
1522
Barry Warsaw53699e91996-12-10 23:23:01 +00001523 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001524 return posix_error();
1525}
1526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001528PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001529"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001530Execute a path with arguments and environment, replacing current process.\n\
1531\n\
1532 path: path of executable file\n\
1533 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001534 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001535
Barry Warsaw53699e91996-12-10 23:23:01 +00001536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001537posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001538{
1539 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001540 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001541 char **argvlist;
1542 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001543 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001544 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001545 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001546
1547 /* execve has three arguments: (path, argv, env), where
1548 argv is a list or tuple of strings and env is a dictionary
1549 like posix.environ. */
1550
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001551 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001552 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001553 if (PyList_Check(argv)) {
1554 argc = PyList_Size(argv);
1555 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001556 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001557 else if (PyTuple_Check(argv)) {
1558 argc = PyTuple_Size(argv);
1559 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001560 }
1561 else {
Fred Drake661ea262000-10-24 19:57:45 +00001562 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001563 return NULL;
1564 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001565 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001566 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001567 return NULL;
1568 }
1569
Guido van Rossum50422b42000-04-26 20:34:28 +00001570 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001571 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001572 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001573 return NULL;
1574 }
1575
Barry Warsaw53699e91996-12-10 23:23:01 +00001576 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001577 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001578 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001579 return NULL;
1580 }
1581 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001582 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001583 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001584 &argvlist[i]))
1585 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001586 goto fail_1;
1587 }
1588 }
1589 argvlist[argc] = NULL;
1590
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001591 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001592 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001593 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001594 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001595 goto fail_1;
1596 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001597 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001598 keys = PyMapping_Keys(env);
1599 vals = PyMapping_Values(env);
1600 if (!keys || !vals)
1601 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001602
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001603 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001604 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001605 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001606
1607 key = PyList_GetItem(keys, pos);
1608 val = PyList_GetItem(vals, pos);
1609 if (!key || !val)
1610 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001611
Fred Drake661ea262000-10-24 19:57:45 +00001612 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1613 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001614 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001615 goto fail_2;
1616 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001617
1618#if defined(PYOS_OS2)
1619 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1620 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1621#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001622 len = PyString_Size(key) + PyString_Size(val) + 2;
1623 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001624 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001625 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001626 goto fail_2;
1627 }
Tim Petersc8996f52001-12-03 20:41:00 +00001628 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001629 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001630#if defined(PYOS_OS2)
1631 }
1632#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001633 }
1634 envlist[envc] = 0;
1635
Guido van Rossumb6775db1994-08-01 11:34:53 +00001636
1637#ifdef BAD_EXEC_PROTOTYPES
1638 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001639#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001640 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001641#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001642
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001643 /* If we get here it's definitely an error */
1644
1645 (void) posix_error();
1646
1647 fail_2:
1648 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001649 PyMem_DEL(envlist[envc]);
1650 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001651 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001652 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001653 Py_XDECREF(vals);
1654 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001655 return NULL;
1656}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001657#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001659
Guido van Rossuma1065681999-01-25 23:20:23 +00001660#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001661PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001662"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001663Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001664\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001665 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001666 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001667 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001668
1669static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001670posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001671{
1672 char *path;
1673 PyObject *argv;
1674 char **argvlist;
1675 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001676 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001677 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001678
1679 /* spawnv has three arguments: (mode, path, argv), where
1680 argv is a list or tuple of strings. */
1681
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001682 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001683 return NULL;
1684 if (PyList_Check(argv)) {
1685 argc = PyList_Size(argv);
1686 getitem = PyList_GetItem;
1687 }
1688 else if (PyTuple_Check(argv)) {
1689 argc = PyTuple_Size(argv);
1690 getitem = PyTuple_GetItem;
1691 }
1692 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001693 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001694 return NULL;
1695 }
1696
1697 argvlist = PyMem_NEW(char *, argc+1);
1698 if (argvlist == NULL)
1699 return NULL;
1700 for (i = 0; i < argc; i++) {
1701 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1702 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001703 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001704 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001705 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001706 }
1707 }
1708 argvlist[argc] = NULL;
1709
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001710#if defined(PYOS_OS2) && defined(PYCC_GCC)
1711 Py_BEGIN_ALLOW_THREADS
1712 spawnval = spawnv(mode, path, argvlist);
1713 Py_END_ALLOW_THREADS
1714#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001715 if (mode == _OLD_P_OVERLAY)
1716 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001717
Tim Peters25059d32001-12-07 20:35:43 +00001718 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001719 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001720 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001721#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001722
Guido van Rossuma1065681999-01-25 23:20:23 +00001723 PyMem_DEL(argvlist);
1724
Fred Drake699f3522000-06-29 21:12:41 +00001725 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001726 return posix_error();
1727 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001728#if SIZEOF_LONG == SIZEOF_VOID_P
1729 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001730#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001731 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001732#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001733}
1734
1735
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001736PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001737"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001738Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001739\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001740 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001741 path: path of executable file\n\
1742 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001743 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001744
1745static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001746posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001747{
1748 char *path;
1749 PyObject *argv, *env;
1750 char **argvlist;
1751 char **envlist;
1752 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1753 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001754 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001755 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001756
1757 /* spawnve has four arguments: (mode, path, argv, env), where
1758 argv is a list or tuple of strings and env is a dictionary
1759 like posix.environ. */
1760
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001761 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001762 return NULL;
1763 if (PyList_Check(argv)) {
1764 argc = PyList_Size(argv);
1765 getitem = PyList_GetItem;
1766 }
1767 else if (PyTuple_Check(argv)) {
1768 argc = PyTuple_Size(argv);
1769 getitem = PyTuple_GetItem;
1770 }
1771 else {
Fred Drake661ea262000-10-24 19:57:45 +00001772 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001773 return NULL;
1774 }
1775 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001776 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001777 return NULL;
1778 }
1779
1780 argvlist = PyMem_NEW(char *, argc+1);
1781 if (argvlist == NULL) {
1782 PyErr_NoMemory();
1783 return NULL;
1784 }
1785 for (i = 0; i < argc; i++) {
1786 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001787 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001788 &argvlist[i]))
1789 {
1790 goto fail_1;
1791 }
1792 }
1793 argvlist[argc] = NULL;
1794
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001795 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001796 envlist = PyMem_NEW(char *, i + 1);
1797 if (envlist == NULL) {
1798 PyErr_NoMemory();
1799 goto fail_1;
1800 }
1801 envc = 0;
1802 keys = PyMapping_Keys(env);
1803 vals = PyMapping_Values(env);
1804 if (!keys || !vals)
1805 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001806
Guido van Rossuma1065681999-01-25 23:20:23 +00001807 for (pos = 0; pos < i; pos++) {
1808 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001809 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001810
1811 key = PyList_GetItem(keys, pos);
1812 val = PyList_GetItem(vals, pos);
1813 if (!key || !val)
1814 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001815
Fred Drake661ea262000-10-24 19:57:45 +00001816 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1817 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001818 {
1819 goto fail_2;
1820 }
Tim Petersc8996f52001-12-03 20:41:00 +00001821 len = PyString_Size(key) + PyString_Size(val) + 2;
1822 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001823 if (p == NULL) {
1824 PyErr_NoMemory();
1825 goto fail_2;
1826 }
Tim Petersc8996f52001-12-03 20:41:00 +00001827 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001828 envlist[envc++] = p;
1829 }
1830 envlist[envc] = 0;
1831
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001832#if defined(PYOS_OS2) && defined(PYCC_GCC)
1833 Py_BEGIN_ALLOW_THREADS
1834 spawnval = spawnve(mode, path, argvlist, envlist);
1835 Py_END_ALLOW_THREADS
1836#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001837 if (mode == _OLD_P_OVERLAY)
1838 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001839
1840 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001841 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001842 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001843#endif
Tim Peters25059d32001-12-07 20:35:43 +00001844
Fred Drake699f3522000-06-29 21:12:41 +00001845 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001846 (void) posix_error();
1847 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001848#if SIZEOF_LONG == SIZEOF_VOID_P
1849 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001850#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001851 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001852#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001853
1854 fail_2:
1855 while (--envc >= 0)
1856 PyMem_DEL(envlist[envc]);
1857 PyMem_DEL(envlist);
1858 fail_1:
1859 PyMem_DEL(argvlist);
1860 Py_XDECREF(vals);
1861 Py_XDECREF(keys);
1862 return res;
1863}
1864#endif /* HAVE_SPAWNV */
1865
1866
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001867#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001868PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001869"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001870Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1871\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001872Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001873
1874static PyObject *
1875posix_fork1(self, args)
1876 PyObject *self;
1877 PyObject *args;
1878{
1879 int pid;
1880 if (!PyArg_ParseTuple(args, ":fork1"))
1881 return NULL;
1882 pid = fork1();
1883 if (pid == -1)
1884 return posix_error();
1885 PyOS_AfterFork();
1886 return PyInt_FromLong((long)pid);
1887}
1888#endif
1889
1890
Guido van Rossumad0ee831995-03-01 10:34:45 +00001891#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001892PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001893"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001894Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001895Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001896
Barry Warsaw53699e91996-12-10 23:23:01 +00001897static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001898posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001899{
1900 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001901 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001902 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001903 pid = fork();
1904 if (pid == -1)
1905 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001906 if (pid == 0)
1907 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001908 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001909}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001910#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001911
Fred Drake8cef4cf2000-06-28 16:40:38 +00001912#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1913#ifdef HAVE_PTY_H
1914#include <pty.h>
1915#else
1916#ifdef HAVE_LIBUTIL_H
1917#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001918#endif /* HAVE_LIBUTIL_H */
1919#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001920#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001921
Thomas Wouters70c21a12000-07-14 14:28:33 +00001922#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001923PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001924"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001925Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001926
1927static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001928posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001929{
1930 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001931#ifndef HAVE_OPENPTY
1932 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001933#endif
1934
Fred Drake8cef4cf2000-06-28 16:40:38 +00001935 if (!PyArg_ParseTuple(args, ":openpty"))
1936 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001937
1938#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001939 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1940 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001941#else
1942 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1943 if (slave_name == NULL)
1944 return posix_error();
1945
1946 slave_fd = open(slave_name, O_RDWR);
1947 if (slave_fd < 0)
1948 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001949#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001950
Fred Drake8cef4cf2000-06-28 16:40:38 +00001951 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001952
Fred Drake8cef4cf2000-06-28 16:40:38 +00001953}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001954#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001955
1956#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001957PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001958"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00001959Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1960Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001961To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001962
1963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001964posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001965{
1966 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00001967
Fred Drake8cef4cf2000-06-28 16:40:38 +00001968 if (!PyArg_ParseTuple(args, ":forkpty"))
1969 return NULL;
1970 pid = forkpty(&master_fd, NULL, NULL, NULL);
1971 if (pid == -1)
1972 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001973 if (pid == 0)
1974 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001975 return Py_BuildValue("(ii)", pid, master_fd);
1976}
1977#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001978
Guido van Rossumad0ee831995-03-01 10:34:45 +00001979#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001980PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001981"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001982Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001983
Barry Warsaw53699e91996-12-10 23:23:01 +00001984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001985posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001986{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001987 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001988 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001989 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001990}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001991#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001993
Guido van Rossumad0ee831995-03-01 10:34:45 +00001994#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001995PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001996"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001997Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001998
Barry Warsaw53699e91996-12-10 23:23:01 +00001999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002000posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002001{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002002 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002003 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002004 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002005}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002006#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002008
Guido van Rossumad0ee831995-03-01 10:34:45 +00002009#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002010PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002011"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002012Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002013
Barry Warsaw53699e91996-12-10 23:23:01 +00002014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002015posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002016{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002017 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002018 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002019 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002020}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002021#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002022
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002023
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002024PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002025"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002026Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002027
Barry Warsaw53699e91996-12-10 23:23:01 +00002028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002029posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002030{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002031 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002032 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002033 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002034}
2035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002036
Fred Drakec9680921999-12-13 16:37:25 +00002037#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002038PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002039"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002040Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002041
2042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002043posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002044{
2045 PyObject *result = NULL;
2046
2047 if (PyArg_ParseTuple(args, ":getgroups")) {
2048#ifdef NGROUPS_MAX
2049#define MAX_GROUPS NGROUPS_MAX
2050#else
2051 /* defined to be 16 on Solaris7, so this should be a small number */
2052#define MAX_GROUPS 64
2053#endif
2054 gid_t grouplist[MAX_GROUPS];
2055 int n;
2056
2057 n = getgroups(MAX_GROUPS, grouplist);
2058 if (n < 0)
2059 posix_error();
2060 else {
2061 result = PyList_New(n);
2062 if (result != NULL) {
2063 PyObject *o;
2064 int i;
2065 for (i = 0; i < n; ++i) {
2066 o = PyInt_FromLong((long)grouplist[i]);
2067 if (o == NULL) {
2068 Py_DECREF(result);
2069 result = NULL;
2070 break;
2071 }
2072 PyList_SET_ITEM(result, i, o);
2073 }
2074 }
2075 }
2076 }
2077 return result;
2078}
2079#endif
2080
Martin v. Löwis606edc12002-06-13 21:09:11 +00002081#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002082PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002083"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002084Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002085
2086static PyObject *
2087posix_getpgid(PyObject *self, PyObject *args)
2088{
2089 int pid, pgid;
2090 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2091 return NULL;
2092 pgid = getpgid(pid);
2093 if (pgid < 0)
2094 return posix_error();
2095 return PyInt_FromLong((long)pgid);
2096}
2097#endif /* HAVE_GETPGID */
2098
2099
Guido van Rossumb6775db1994-08-01 11:34:53 +00002100#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002101PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002102"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002103Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002104
Barry Warsaw53699e91996-12-10 23:23:01 +00002105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002106posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002107{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002108 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002109 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002110#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002111 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002112#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002113 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002114#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002115}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002116#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002118
Guido van Rossumb6775db1994-08-01 11:34:53 +00002119#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002120PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002121"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002122Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002123
Barry Warsaw53699e91996-12-10 23:23:01 +00002124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002125posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002126{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002127 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002128 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002129#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002130 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002131#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002132 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002133#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002134 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002135 Py_INCREF(Py_None);
2136 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002137}
2138
Guido van Rossumb6775db1994-08-01 11:34:53 +00002139#endif /* HAVE_SETPGRP */
2140
Guido van Rossumad0ee831995-03-01 10:34:45 +00002141#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002143"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002144Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002145
Barry Warsaw53699e91996-12-10 23:23:01 +00002146static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002147posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002148{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002149 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002150 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002151 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002152}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002153#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002155
Fred Drake12c6e2d1999-12-14 21:25:03 +00002156#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002157PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002158"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002159Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002160
2161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002162posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002163{
2164 PyObject *result = NULL;
2165
2166 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002167 char *name;
2168 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002169
Fred Drakea30680b2000-12-06 21:24:28 +00002170 errno = 0;
2171 name = getlogin();
2172 if (name == NULL) {
2173 if (errno)
2174 posix_error();
2175 else
2176 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002177 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002178 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002179 else
2180 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002181 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002182 }
2183 return result;
2184}
2185#endif
2186
Guido van Rossumad0ee831995-03-01 10:34:45 +00002187#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002188PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002189"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002190Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002191
Barry Warsaw53699e91996-12-10 23:23:01 +00002192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002193posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002194{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002195 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002196 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002197 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002198}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002199#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002201
Guido van Rossumad0ee831995-03-01 10:34:45 +00002202#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002203PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002204"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002205Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002206
Barry Warsaw53699e91996-12-10 23:23:01 +00002207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002208posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002209{
2210 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002211 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002212 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002213#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002214 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2215 APIRET rc;
2216 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002217 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002218
2219 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2220 APIRET rc;
2221 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002222 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002223
2224 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002225 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002226#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002227 if (kill(pid, sig) == -1)
2228 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002229#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002230 Py_INCREF(Py_None);
2231 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002232}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002233#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002234
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002235#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002236PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002237"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002238Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002239
2240static PyObject *
2241posix_killpg(PyObject *self, PyObject *args)
2242{
2243 int pgid, sig;
2244 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2245 return NULL;
2246 if (killpg(pgid, sig) == -1)
2247 return posix_error();
2248 Py_INCREF(Py_None);
2249 return Py_None;
2250}
2251#endif
2252
Guido van Rossumc0125471996-06-28 18:55:32 +00002253#ifdef HAVE_PLOCK
2254
2255#ifdef HAVE_SYS_LOCK_H
2256#include <sys/lock.h>
2257#endif
2258
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002259PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002260"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002261Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002262
Barry Warsaw53699e91996-12-10 23:23:01 +00002263static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002264posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002265{
2266 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002267 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002268 return NULL;
2269 if (plock(op) == -1)
2270 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002271 Py_INCREF(Py_None);
2272 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002273}
2274#endif
2275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002276
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002277#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002278PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002279"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002280Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002281
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002282#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002283#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002284static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002285async_system(const char *command)
2286{
2287 char *p, errormsg[256], args[1024];
2288 RESULTCODES rcodes;
2289 APIRET rc;
2290 char *shell = getenv("COMSPEC");
2291 if (!shell)
2292 shell = "cmd";
2293
2294 strcpy(args, shell);
2295 p = &args[ strlen(args)+1 ];
2296 strcpy(p, "/c ");
2297 strcat(p, command);
2298 p += strlen(p) + 1;
2299 *p = '\0';
2300
2301 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002302 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002303 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002304 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002305 &rcodes, shell);
2306 return rc;
2307}
2308
Guido van Rossumd48f2521997-12-05 22:19:34 +00002309static FILE *
2310popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002311{
2312 HFILE rhan, whan;
2313 FILE *retfd = NULL;
2314 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2315
Guido van Rossumd48f2521997-12-05 22:19:34 +00002316 if (rc != NO_ERROR) {
2317 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002318 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002319 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002320
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002321 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2322 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002324 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2325 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002326
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002327 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2328 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002329
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002330 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002331 }
2332
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002333 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2334 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002335
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002336 if (rc == NO_ERROR)
2337 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2338
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002339 close(oldfd); /* And Close Saved STDOUT Handle */
2340 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002341
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002342 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2343 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002344
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002345 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2346 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002347
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002348 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2349 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002350
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002351 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002352 }
2353
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002354 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2355 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002356
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002357 if (rc == NO_ERROR)
2358 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2359
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002360 close(oldfd); /* And Close Saved STDIN Handle */
2361 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002362
Guido van Rossumd48f2521997-12-05 22:19:34 +00002363 } else {
2364 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002365 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002366 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002367}
2368
2369static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002370posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002371{
2372 char *name;
2373 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002374 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002375 FILE *fp;
2376 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002377 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002378 return NULL;
2379 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002380 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002381 Py_END_ALLOW_THREADS
2382 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002383 return os2_error(err);
2384
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002385 f = PyFile_FromFile(fp, name, mode, fclose);
2386 if (f != NULL)
2387 PyFile_SetBufSize(f, bufsize);
2388 return f;
2389}
2390
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002391#elif defined(PYCC_GCC)
2392
2393/* standard posix version of popen() support */
2394static PyObject *
2395posix_popen(PyObject *self, PyObject *args)
2396{
2397 char *name;
2398 char *mode = "r";
2399 int bufsize = -1;
2400 FILE *fp;
2401 PyObject *f;
2402 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2403 return NULL;
2404 Py_BEGIN_ALLOW_THREADS
2405 fp = popen(name, mode);
2406 Py_END_ALLOW_THREADS
2407 if (fp == NULL)
2408 return posix_error();
2409 f = PyFile_FromFile(fp, name, mode, pclose);
2410 if (f != NULL)
2411 PyFile_SetBufSize(f, bufsize);
2412 return f;
2413}
2414
2415/* fork() under OS/2 has lots'o'warts
2416 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2417 * most of this code is a ripoff of the win32 code, but using the
2418 * capabilities of EMX's C library routines
2419 */
2420
2421/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2422#define POPEN_1 1
2423#define POPEN_2 2
2424#define POPEN_3 3
2425#define POPEN_4 4
2426
2427static PyObject *_PyPopen(char *, int, int, int);
2428static int _PyPclose(FILE *file);
2429
2430/*
2431 * Internal dictionary mapping popen* file pointers to process handles,
2432 * for use when retrieving the process exit code. See _PyPclose() below
2433 * for more information on this dictionary's use.
2434 */
2435static PyObject *_PyPopenProcs = NULL;
2436
2437/* os2emx version of popen2()
2438 *
2439 * The result of this function is a pipe (file) connected to the
2440 * process's stdin, and a pipe connected to the process's stdout.
2441 */
2442
2443static PyObject *
2444os2emx_popen2(PyObject *self, PyObject *args)
2445{
2446 PyObject *f;
2447 int tm=0;
2448
2449 char *cmdstring;
2450 char *mode = "t";
2451 int bufsize = -1;
2452 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2453 return NULL;
2454
2455 if (*mode == 't')
2456 tm = O_TEXT;
2457 else if (*mode != 'b') {
2458 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2459 return NULL;
2460 } else
2461 tm = O_BINARY;
2462
2463 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2464
2465 return f;
2466}
2467
2468/*
2469 * Variation on os2emx.popen2
2470 *
2471 * The result of this function is 3 pipes - the process's stdin,
2472 * stdout and stderr
2473 */
2474
2475static PyObject *
2476os2emx_popen3(PyObject *self, PyObject *args)
2477{
2478 PyObject *f;
2479 int tm = 0;
2480
2481 char *cmdstring;
2482 char *mode = "t";
2483 int bufsize = -1;
2484 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2485 return NULL;
2486
2487 if (*mode == 't')
2488 tm = O_TEXT;
2489 else if (*mode != 'b') {
2490 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2491 return NULL;
2492 } else
2493 tm = O_BINARY;
2494
2495 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2496
2497 return f;
2498}
2499
2500/*
2501 * Variation on os2emx.popen2
2502 *
2503 * The result of this function is 2 pipes - the processes stdin,
2504 * and stdout+stderr combined as a single pipe.
2505 */
2506
2507static PyObject *
2508os2emx_popen4(PyObject *self, PyObject *args)
2509{
2510 PyObject *f;
2511 int tm = 0;
2512
2513 char *cmdstring;
2514 char *mode = "t";
2515 int bufsize = -1;
2516 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2517 return NULL;
2518
2519 if (*mode == 't')
2520 tm = O_TEXT;
2521 else if (*mode != 'b') {
2522 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2523 return NULL;
2524 } else
2525 tm = O_BINARY;
2526
2527 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2528
2529 return f;
2530}
2531
2532/* a couple of structures for convenient handling of multiple
2533 * file handles and pipes
2534 */
2535struct file_ref
2536{
2537 int handle;
2538 int flags;
2539};
2540
2541struct pipe_ref
2542{
2543 int rd;
2544 int wr;
2545};
2546
2547/* The following code is derived from the win32 code */
2548
2549static PyObject *
2550_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2551{
2552 struct file_ref stdio[3];
2553 struct pipe_ref p_fd[3];
2554 FILE *p_s[3];
2555 int file_count, i, pipe_err, pipe_pid;
2556 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2557 PyObject *f, *p_f[3];
2558
2559 /* file modes for subsequent fdopen's on pipe handles */
2560 if (mode == O_TEXT)
2561 {
2562 rd_mode = "rt";
2563 wr_mode = "wt";
2564 }
2565 else
2566 {
2567 rd_mode = "rb";
2568 wr_mode = "wb";
2569 }
2570
2571 /* prepare shell references */
2572 if ((shell = getenv("EMXSHELL")) == NULL)
2573 if ((shell = getenv("COMSPEC")) == NULL)
2574 {
2575 errno = ENOENT;
2576 return posix_error();
2577 }
2578
2579 sh_name = _getname(shell);
2580 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2581 opt = "/c";
2582 else
2583 opt = "-c";
2584
2585 /* save current stdio fds + their flags, and set not inheritable */
2586 i = pipe_err = 0;
2587 while (pipe_err >= 0 && i < 3)
2588 {
2589 pipe_err = stdio[i].handle = dup(i);
2590 stdio[i].flags = fcntl(i, F_GETFD, 0);
2591 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2592 i++;
2593 }
2594 if (pipe_err < 0)
2595 {
2596 /* didn't get them all saved - clean up and bail out */
2597 int saved_err = errno;
2598 while (i-- > 0)
2599 {
2600 close(stdio[i].handle);
2601 }
2602 errno = saved_err;
2603 return posix_error();
2604 }
2605
2606 /* create pipe ends */
2607 file_count = 2;
2608 if (n == POPEN_3)
2609 file_count = 3;
2610 i = pipe_err = 0;
2611 while ((pipe_err == 0) && (i < file_count))
2612 pipe_err = pipe((int *)&p_fd[i++]);
2613 if (pipe_err < 0)
2614 {
2615 /* didn't get them all made - clean up and bail out */
2616 while (i-- > 0)
2617 {
2618 close(p_fd[i].wr);
2619 close(p_fd[i].rd);
2620 }
2621 errno = EPIPE;
2622 return posix_error();
2623 }
2624
2625 /* change the actual standard IO streams over temporarily,
2626 * making the retained pipe ends non-inheritable
2627 */
2628 pipe_err = 0;
2629
2630 /* - stdin */
2631 if (dup2(p_fd[0].rd, 0) == 0)
2632 {
2633 close(p_fd[0].rd);
2634 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2635 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2636 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2637 {
2638 close(p_fd[0].wr);
2639 pipe_err = -1;
2640 }
2641 }
2642 else
2643 {
2644 pipe_err = -1;
2645 }
2646
2647 /* - stdout */
2648 if (pipe_err == 0)
2649 {
2650 if (dup2(p_fd[1].wr, 1) == 1)
2651 {
2652 close(p_fd[1].wr);
2653 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2654 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2655 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2656 {
2657 close(p_fd[1].rd);
2658 pipe_err = -1;
2659 }
2660 }
2661 else
2662 {
2663 pipe_err = -1;
2664 }
2665 }
2666
2667 /* - stderr, as required */
2668 if (pipe_err == 0)
2669 switch (n)
2670 {
2671 case POPEN_3:
2672 {
2673 if (dup2(p_fd[2].wr, 2) == 2)
2674 {
2675 close(p_fd[2].wr);
2676 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2677 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2678 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2679 {
2680 close(p_fd[2].rd);
2681 pipe_err = -1;
2682 }
2683 }
2684 else
2685 {
2686 pipe_err = -1;
2687 }
2688 break;
2689 }
2690
2691 case POPEN_4:
2692 {
2693 if (dup2(1, 2) != 2)
2694 {
2695 pipe_err = -1;
2696 }
2697 break;
2698 }
2699 }
2700
2701 /* spawn the child process */
2702 if (pipe_err == 0)
2703 {
2704 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2705 if (pipe_pid == -1)
2706 {
2707 pipe_err = -1;
2708 }
2709 else
2710 {
2711 /* save the PID into the FILE structure
2712 * NOTE: this implementation doesn't actually
2713 * take advantage of this, but do it for
2714 * completeness - AIM Apr01
2715 */
2716 for (i = 0; i < file_count; i++)
2717 p_s[i]->_pid = pipe_pid;
2718 }
2719 }
2720
2721 /* reset standard IO to normal */
2722 for (i = 0; i < 3; i++)
2723 {
2724 dup2(stdio[i].handle, i);
2725 fcntl(i, F_SETFD, stdio[i].flags);
2726 close(stdio[i].handle);
2727 }
2728
2729 /* if any remnant problems, clean up and bail out */
2730 if (pipe_err < 0)
2731 {
2732 for (i = 0; i < 3; i++)
2733 {
2734 close(p_fd[i].rd);
2735 close(p_fd[i].wr);
2736 }
2737 errno = EPIPE;
2738 return posix_error_with_filename(cmdstring);
2739 }
2740
2741 /* build tuple of file objects to return */
2742 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2743 PyFile_SetBufSize(p_f[0], bufsize);
2744 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2745 PyFile_SetBufSize(p_f[1], bufsize);
2746 if (n == POPEN_3)
2747 {
2748 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2749 PyFile_SetBufSize(p_f[0], bufsize);
2750 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2751 }
2752 else
2753 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2754
2755 /*
2756 * Insert the files we've created into the process dictionary
2757 * all referencing the list with the process handle and the
2758 * initial number of files (see description below in _PyPclose).
2759 * Since if _PyPclose later tried to wait on a process when all
2760 * handles weren't closed, it could create a deadlock with the
2761 * child, we spend some energy here to try to ensure that we
2762 * either insert all file handles into the dictionary or none
2763 * at all. It's a little clumsy with the various popen modes
2764 * and variable number of files involved.
2765 */
2766 if (!_PyPopenProcs)
2767 {
2768 _PyPopenProcs = PyDict_New();
2769 }
2770
2771 if (_PyPopenProcs)
2772 {
2773 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2774 int ins_rc[3];
2775
2776 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2777 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2778
2779 procObj = PyList_New(2);
2780 pidObj = PyInt_FromLong((long) pipe_pid);
2781 intObj = PyInt_FromLong((long) file_count);
2782
2783 if (procObj && pidObj && intObj)
2784 {
2785 PyList_SetItem(procObj, 0, pidObj);
2786 PyList_SetItem(procObj, 1, intObj);
2787
2788 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2789 if (fileObj[0])
2790 {
2791 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2792 fileObj[0],
2793 procObj);
2794 }
2795 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2796 if (fileObj[1])
2797 {
2798 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2799 fileObj[1],
2800 procObj);
2801 }
2802 if (file_count >= 3)
2803 {
2804 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2805 if (fileObj[2])
2806 {
2807 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2808 fileObj[2],
2809 procObj);
2810 }
2811 }
2812
2813 if (ins_rc[0] < 0 || !fileObj[0] ||
2814 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2815 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2816 {
2817 /* Something failed - remove any dictionary
2818 * entries that did make it.
2819 */
2820 if (!ins_rc[0] && fileObj[0])
2821 {
2822 PyDict_DelItem(_PyPopenProcs,
2823 fileObj[0]);
2824 }
2825 if (!ins_rc[1] && fileObj[1])
2826 {
2827 PyDict_DelItem(_PyPopenProcs,
2828 fileObj[1]);
2829 }
2830 if (!ins_rc[2] && fileObj[2])
2831 {
2832 PyDict_DelItem(_PyPopenProcs,
2833 fileObj[2]);
2834 }
2835 }
2836 }
2837
2838 /*
2839 * Clean up our localized references for the dictionary keys
2840 * and value since PyDict_SetItem will Py_INCREF any copies
2841 * that got placed in the dictionary.
2842 */
2843 Py_XDECREF(procObj);
2844 Py_XDECREF(fileObj[0]);
2845 Py_XDECREF(fileObj[1]);
2846 Py_XDECREF(fileObj[2]);
2847 }
2848
2849 /* Child is launched. */
2850 return f;
2851}
2852
2853/*
2854 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2855 * exit code for the child process and return as a result of the close.
2856 *
2857 * This function uses the _PyPopenProcs dictionary in order to map the
2858 * input file pointer to information about the process that was
2859 * originally created by the popen* call that created the file pointer.
2860 * The dictionary uses the file pointer as a key (with one entry
2861 * inserted for each file returned by the original popen* call) and a
2862 * single list object as the value for all files from a single call.
2863 * The list object contains the Win32 process handle at [0], and a file
2864 * count at [1], which is initialized to the total number of file
2865 * handles using that list.
2866 *
2867 * This function closes whichever handle it is passed, and decrements
2868 * the file count in the dictionary for the process handle pointed to
2869 * by this file. On the last close (when the file count reaches zero),
2870 * this function will wait for the child process and then return its
2871 * exit code as the result of the close() operation. This permits the
2872 * files to be closed in any order - it is always the close() of the
2873 * final handle that will return the exit code.
2874 */
2875
2876 /* RED_FLAG 31-Aug-2000 Tim
2877 * This is always called (today!) between a pair of
2878 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2879 * macros. So the thread running this has no valid thread state, as
2880 * far as Python is concerned. However, this calls some Python API
2881 * functions that cannot be called safely without a valid thread
2882 * state, in particular PyDict_GetItem.
2883 * As a temporary hack (although it may last for years ...), we
2884 * *rely* on not having a valid thread state in this function, in
2885 * order to create our own "from scratch".
2886 * This will deadlock if _PyPclose is ever called by a thread
2887 * holding the global lock.
2888 * (The OS/2 EMX thread support appears to cover the case where the
2889 * lock is already held - AIM Apr01)
2890 */
2891
2892static int _PyPclose(FILE *file)
2893{
2894 int result;
2895 int exit_code;
2896 int pipe_pid;
2897 PyObject *procObj, *pidObj, *intObj, *fileObj;
2898 int file_count;
2899#ifdef WITH_THREAD
2900 PyInterpreterState* pInterpreterState;
2901 PyThreadState* pThreadState;
2902#endif
2903
2904 /* Close the file handle first, to ensure it can't block the
2905 * child from exiting if it's the last handle.
2906 */
2907 result = fclose(file);
2908
2909#ifdef WITH_THREAD
2910 /* Bootstrap a valid thread state into existence. */
2911 pInterpreterState = PyInterpreterState_New();
2912 if (!pInterpreterState) {
2913 /* Well, we're hosed now! We don't have a thread
2914 * state, so can't call a nice error routine, or raise
2915 * an exception. Just die.
2916 */
2917 Py_FatalError("unable to allocate interpreter state "
2918 "when closing popen object.");
2919 return -1; /* unreachable */
2920 }
2921 pThreadState = PyThreadState_New(pInterpreterState);
2922 if (!pThreadState) {
2923 Py_FatalError("unable to allocate thread state "
2924 "when closing popen object.");
2925 return -1; /* unreachable */
2926 }
2927 /* Grab the global lock. Note that this will deadlock if the
2928 * current thread already has the lock! (see RED_FLAG comments
2929 * before this function)
2930 */
2931 PyEval_RestoreThread(pThreadState);
2932#endif
2933
2934 if (_PyPopenProcs)
2935 {
2936 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2937 (procObj = PyDict_GetItem(_PyPopenProcs,
2938 fileObj)) != NULL &&
2939 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2940 (intObj = PyList_GetItem(procObj,1)) != NULL)
2941 {
2942 pipe_pid = (int) PyInt_AsLong(pidObj);
2943 file_count = (int) PyInt_AsLong(intObj);
2944
2945 if (file_count > 1)
2946 {
2947 /* Still other files referencing process */
2948 file_count--;
2949 PyList_SetItem(procObj,1,
2950 PyInt_FromLong((long) file_count));
2951 }
2952 else
2953 {
2954 /* Last file for this process */
2955 if (result != EOF &&
2956 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2957 {
2958 /* extract exit status */
2959 if (WIFEXITED(exit_code))
2960 {
2961 result = WEXITSTATUS(exit_code);
2962 }
2963 else
2964 {
2965 errno = EPIPE;
2966 result = -1;
2967 }
2968 }
2969 else
2970 {
2971 /* Indicate failure - this will cause the file object
2972 * to raise an I/O error and translate the last
2973 * error code from errno. We do have a problem with
2974 * last errors that overlap the normal errno table,
2975 * but that's a consistent problem with the file object.
2976 */
2977 result = -1;
2978 }
2979 }
2980
2981 /* Remove this file pointer from dictionary */
2982 PyDict_DelItem(_PyPopenProcs, fileObj);
2983
2984 if (PyDict_Size(_PyPopenProcs) == 0)
2985 {
2986 Py_DECREF(_PyPopenProcs);
2987 _PyPopenProcs = NULL;
2988 }
2989
2990 } /* if object retrieval ok */
2991
2992 Py_XDECREF(fileObj);
2993 } /* if _PyPopenProcs */
2994
2995#ifdef WITH_THREAD
2996 /* Tear down the thread & interpreter states.
2997 * Note that interpreter state clear & delete functions automatically
2998 * call the thread clear & delete functions, and indeed insist on
2999 * doing that themselves. The lock must be held during the clear, but
3000 * need not be held during the delete.
3001 */
3002 PyInterpreterState_Clear(pInterpreterState);
3003 PyEval_ReleaseThread(pThreadState);
3004 PyInterpreterState_Delete(pInterpreterState);
3005#endif
3006
3007 return result;
3008}
3009
3010#endif /* PYCC_??? */
3011
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003012#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003013
3014/*
3015 * Portable 'popen' replacement for Win32.
3016 *
3017 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3018 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003019 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003020 */
3021
3022#include <malloc.h>
3023#include <io.h>
3024#include <fcntl.h>
3025
3026/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3027#define POPEN_1 1
3028#define POPEN_2 2
3029#define POPEN_3 3
3030#define POPEN_4 4
3031
3032static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003033static int _PyPclose(FILE *file);
3034
3035/*
3036 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003037 * for use when retrieving the process exit code. See _PyPclose() below
3038 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003039 */
3040static PyObject *_PyPopenProcs = NULL;
3041
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003042
3043/* popen that works from a GUI.
3044 *
3045 * The result of this function is a pipe (file) connected to the
3046 * processes stdin or stdout, depending on the requested mode.
3047 */
3048
3049static PyObject *
3050posix_popen(PyObject *self, PyObject *args)
3051{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003052 PyObject *f, *s;
3053 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003054
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003055 char *cmdstring;
3056 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003057 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003058 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003059 return NULL;
3060
3061 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003062
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003063 if (*mode == 'r')
3064 tm = _O_RDONLY;
3065 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003066 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003067 return NULL;
3068 } else
3069 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003070
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003071 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003072 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003073 return NULL;
3074 }
3075
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003076 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003077 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003078 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003079 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003080 else
3081 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3082
3083 return f;
3084}
3085
3086/* Variation on win32pipe.popen
3087 *
3088 * The result of this function is a pipe (file) connected to the
3089 * process's stdin, and a pipe connected to the process's stdout.
3090 */
3091
3092static PyObject *
3093win32_popen2(PyObject *self, PyObject *args)
3094{
3095 PyObject *f;
3096 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003097
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003098 char *cmdstring;
3099 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003100 int bufsize = -1;
3101 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003102 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003103
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003104 if (*mode == 't')
3105 tm = _O_TEXT;
3106 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003107 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003108 return NULL;
3109 } else
3110 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003111
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003112 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003113 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003114 return NULL;
3115 }
3116
3117 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003118
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003119 return f;
3120}
3121
3122/*
3123 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003124 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003125 * The result of this function is 3 pipes - the process's stdin,
3126 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003127 */
3128
3129static PyObject *
3130win32_popen3(PyObject *self, PyObject *args)
3131{
3132 PyObject *f;
3133 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003134
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003135 char *cmdstring;
3136 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003137 int bufsize = -1;
3138 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003139 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003140
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003141 if (*mode == 't')
3142 tm = _O_TEXT;
3143 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003144 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003145 return NULL;
3146 } else
3147 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003148
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003149 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003150 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003151 return NULL;
3152 }
3153
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003154 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003155
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003156 return f;
3157}
3158
3159/*
3160 * Variation on win32pipe.popen
3161 *
Tim Peters5aa91602002-01-30 05:46:57 +00003162 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003163 * and stdout+stderr combined as a single pipe.
3164 */
3165
3166static PyObject *
3167win32_popen4(PyObject *self, PyObject *args)
3168{
3169 PyObject *f;
3170 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003171
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003172 char *cmdstring;
3173 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003174 int bufsize = -1;
3175 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003176 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003177
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003178 if (*mode == 't')
3179 tm = _O_TEXT;
3180 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003181 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003182 return NULL;
3183 } else
3184 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003185
3186 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003187 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003188 return NULL;
3189 }
3190
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003191 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003192
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003193 return f;
3194}
3195
Mark Hammond08501372001-01-31 07:30:29 +00003196static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003197_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003198 HANDLE hStdin,
3199 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003200 HANDLE hStderr,
3201 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003202{
3203 PROCESS_INFORMATION piProcInfo;
3204 STARTUPINFO siStartInfo;
3205 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003206 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003207 int i;
3208 int x;
3209
3210 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003211 char *comshell;
3212
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003213 s1 = (char *)_alloca(i);
3214 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3215 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003216
3217 /* Explicitly check if we are using COMMAND.COM. If we are
3218 * then use the w9xpopen hack.
3219 */
3220 comshell = s1 + x;
3221 while (comshell >= s1 && *comshell != '\\')
3222 --comshell;
3223 ++comshell;
3224
3225 if (GetVersion() < 0x80000000 &&
3226 _stricmp(comshell, "command.com") != 0) {
3227 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003228 x = i + strlen(s3) + strlen(cmdstring) + 1;
3229 s2 = (char *)_alloca(x);
3230 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003231 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003232 }
3233 else {
3234 /*
Tim Peters402d5982001-08-27 06:37:48 +00003235 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3236 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003237 */
Mark Hammond08501372001-01-31 07:30:29 +00003238 char modulepath[_MAX_PATH];
3239 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003240 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3241 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003242 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003243 x = i+1;
3244 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003245 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003246 strncat(modulepath,
3247 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003248 (sizeof(modulepath)/sizeof(modulepath[0]))
3249 -strlen(modulepath));
3250 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003251 /* Eeek - file-not-found - possibly an embedding
3252 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003253 */
Tim Peters5aa91602002-01-30 05:46:57 +00003254 strncpy(modulepath,
3255 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003256 sizeof(modulepath)/sizeof(modulepath[0]));
3257 if (modulepath[strlen(modulepath)-1] != '\\')
3258 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003259 strncat(modulepath,
3260 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003261 (sizeof(modulepath)/sizeof(modulepath[0]))
3262 -strlen(modulepath));
3263 /* No where else to look - raise an easily identifiable
3264 error, rather than leaving Windows to report
3265 "file not found" - as the user is probably blissfully
3266 unaware this shim EXE is used, and it will confuse them.
3267 (well, it confused me for a while ;-)
3268 */
3269 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003270 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003271 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003272 "for popen to work with your shell "
3273 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003274 szConsoleSpawn);
3275 return FALSE;
3276 }
3277 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003278 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003279 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003280 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003281
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003282 s2 = (char *)_alloca(x);
3283 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003284 /* To maintain correct argument passing semantics,
3285 we pass the command-line as it stands, and allow
3286 quoting to be applied. w9xpopen.exe will then
3287 use its argv vector, and re-quote the necessary
3288 args for the ultimate child process.
3289 */
Tim Peters75cdad52001-11-28 22:07:30 +00003290 PyOS_snprintf(
3291 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003292 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003293 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003294 s1,
3295 s3,
3296 cmdstring);
3297 }
3298 }
3299
3300 /* Could be an else here to try cmd.exe / command.com in the path
3301 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003302 else {
Tim Peters402d5982001-08-27 06:37:48 +00003303 PyErr_SetString(PyExc_RuntimeError,
3304 "Cannot locate a COMSPEC environment variable to "
3305 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003306 return FALSE;
3307 }
Tim Peters5aa91602002-01-30 05:46:57 +00003308
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003309 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3310 siStartInfo.cb = sizeof(STARTUPINFO);
3311 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3312 siStartInfo.hStdInput = hStdin;
3313 siStartInfo.hStdOutput = hStdout;
3314 siStartInfo.hStdError = hStderr;
3315 siStartInfo.wShowWindow = SW_HIDE;
3316
3317 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003318 s2,
3319 NULL,
3320 NULL,
3321 TRUE,
Mark Hammond155adbd2002-07-14 23:28:16 +00003322 0, /* no new console so Ctrl+C kills child too */
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003323 NULL,
3324 NULL,
3325 &siStartInfo,
3326 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003327 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003328 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003329
Mark Hammondb37a3732000-08-14 04:47:33 +00003330 /* Return process handle */
3331 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003332 return TRUE;
3333 }
Tim Peters402d5982001-08-27 06:37:48 +00003334 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003335 return FALSE;
3336}
3337
3338/* The following code is based off of KB: Q190351 */
3339
3340static PyObject *
3341_PyPopen(char *cmdstring, int mode, int n)
3342{
3343 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3344 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003345 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003346
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003347 SECURITY_ATTRIBUTES saAttr;
3348 BOOL fSuccess;
3349 int fd1, fd2, fd3;
3350 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003351 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003352 PyObject *f;
3353
3354 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3355 saAttr.bInheritHandle = TRUE;
3356 saAttr.lpSecurityDescriptor = NULL;
3357
3358 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3359 return win32_error("CreatePipe", NULL);
3360
3361 /* Create new output read handle and the input write handle. Set
3362 * the inheritance properties to FALSE. Otherwise, the child inherits
3363 * the these handles; resulting in non-closeable handles to the pipes
3364 * being created. */
3365 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003366 GetCurrentProcess(), &hChildStdinWrDup, 0,
3367 FALSE,
3368 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003369 if (!fSuccess)
3370 return win32_error("DuplicateHandle", NULL);
3371
3372 /* Close the inheritable version of ChildStdin
3373 that we're using. */
3374 CloseHandle(hChildStdinWr);
3375
3376 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3377 return win32_error("CreatePipe", NULL);
3378
3379 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003380 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3381 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003382 if (!fSuccess)
3383 return win32_error("DuplicateHandle", NULL);
3384
3385 /* Close the inheritable version of ChildStdout
3386 that we're using. */
3387 CloseHandle(hChildStdoutRd);
3388
3389 if (n != POPEN_4) {
3390 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3391 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003392 fSuccess = DuplicateHandle(GetCurrentProcess(),
3393 hChildStderrRd,
3394 GetCurrentProcess(),
3395 &hChildStderrRdDup, 0,
3396 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003397 if (!fSuccess)
3398 return win32_error("DuplicateHandle", NULL);
3399 /* Close the inheritable version of ChildStdErr that we're using. */
3400 CloseHandle(hChildStderrRd);
3401 }
Tim Peters5aa91602002-01-30 05:46:57 +00003402
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003403 switch (n) {
3404 case POPEN_1:
3405 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3406 case _O_WRONLY | _O_TEXT:
3407 /* Case for writing to child Stdin in text mode. */
3408 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3409 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003410 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003411 PyFile_SetBufSize(f, 0);
3412 /* We don't care about these pipes anymore, so close them. */
3413 CloseHandle(hChildStdoutRdDup);
3414 CloseHandle(hChildStderrRdDup);
3415 break;
3416
3417 case _O_RDONLY | _O_TEXT:
3418 /* Case for reading from child Stdout in text mode. */
3419 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3420 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003421 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003422 PyFile_SetBufSize(f, 0);
3423 /* We don't care about these pipes anymore, so close them. */
3424 CloseHandle(hChildStdinWrDup);
3425 CloseHandle(hChildStderrRdDup);
3426 break;
3427
3428 case _O_RDONLY | _O_BINARY:
3429 /* Case for readinig from child Stdout in binary mode. */
3430 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3431 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003432 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003433 PyFile_SetBufSize(f, 0);
3434 /* We don't care about these pipes anymore, so close them. */
3435 CloseHandle(hChildStdinWrDup);
3436 CloseHandle(hChildStderrRdDup);
3437 break;
3438
3439 case _O_WRONLY | _O_BINARY:
3440 /* Case for writing to child Stdin in binary mode. */
3441 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3442 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003443 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003444 PyFile_SetBufSize(f, 0);
3445 /* We don't care about these pipes anymore, so close them. */
3446 CloseHandle(hChildStdoutRdDup);
3447 CloseHandle(hChildStderrRdDup);
3448 break;
3449 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003450 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003451 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003452
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003453 case POPEN_2:
3454 case POPEN_4:
3455 {
3456 char *m1, *m2;
3457 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003458
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003459 if (mode && _O_TEXT) {
3460 m1 = "r";
3461 m2 = "w";
3462 } else {
3463 m1 = "rb";
3464 m2 = "wb";
3465 }
3466
3467 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3468 f1 = _fdopen(fd1, m2);
3469 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3470 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003471 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003472 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003473 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003474 PyFile_SetBufSize(p2, 0);
3475
3476 if (n != 4)
3477 CloseHandle(hChildStderrRdDup);
3478
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003479 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003480 Py_XDECREF(p1);
3481 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003482 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003483 break;
3484 }
Tim Peters5aa91602002-01-30 05:46:57 +00003485
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003486 case POPEN_3:
3487 {
3488 char *m1, *m2;
3489 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003490
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003491 if (mode && _O_TEXT) {
3492 m1 = "r";
3493 m2 = "w";
3494 } else {
3495 m1 = "rb";
3496 m2 = "wb";
3497 }
3498
3499 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3500 f1 = _fdopen(fd1, m2);
3501 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3502 f2 = _fdopen(fd2, m1);
3503 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3504 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003505 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003506 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3507 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003508 PyFile_SetBufSize(p1, 0);
3509 PyFile_SetBufSize(p2, 0);
3510 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003511 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003512 Py_XDECREF(p1);
3513 Py_XDECREF(p2);
3514 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003515 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003516 break;
3517 }
3518 }
3519
3520 if (n == POPEN_4) {
3521 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003522 hChildStdinRd,
3523 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003524 hChildStdoutWr,
3525 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003526 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003527 }
3528 else {
3529 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003530 hChildStdinRd,
3531 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003532 hChildStderrWr,
3533 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003534 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003535 }
3536
Mark Hammondb37a3732000-08-14 04:47:33 +00003537 /*
3538 * Insert the files we've created into the process dictionary
3539 * all referencing the list with the process handle and the
3540 * initial number of files (see description below in _PyPclose).
3541 * Since if _PyPclose later tried to wait on a process when all
3542 * handles weren't closed, it could create a deadlock with the
3543 * child, we spend some energy here to try to ensure that we
3544 * either insert all file handles into the dictionary or none
3545 * at all. It's a little clumsy with the various popen modes
3546 * and variable number of files involved.
3547 */
3548 if (!_PyPopenProcs) {
3549 _PyPopenProcs = PyDict_New();
3550 }
3551
3552 if (_PyPopenProcs) {
3553 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3554 int ins_rc[3];
3555
3556 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3557 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3558
3559 procObj = PyList_New(2);
3560 hProcessObj = PyLong_FromVoidPtr(hProcess);
3561 intObj = PyInt_FromLong(file_count);
3562
3563 if (procObj && hProcessObj && intObj) {
3564 PyList_SetItem(procObj,0,hProcessObj);
3565 PyList_SetItem(procObj,1,intObj);
3566
3567 fileObj[0] = PyLong_FromVoidPtr(f1);
3568 if (fileObj[0]) {
3569 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3570 fileObj[0],
3571 procObj);
3572 }
3573 if (file_count >= 2) {
3574 fileObj[1] = PyLong_FromVoidPtr(f2);
3575 if (fileObj[1]) {
3576 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3577 fileObj[1],
3578 procObj);
3579 }
3580 }
3581 if (file_count >= 3) {
3582 fileObj[2] = PyLong_FromVoidPtr(f3);
3583 if (fileObj[2]) {
3584 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3585 fileObj[2],
3586 procObj);
3587 }
3588 }
3589
3590 if (ins_rc[0] < 0 || !fileObj[0] ||
3591 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3592 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3593 /* Something failed - remove any dictionary
3594 * entries that did make it.
3595 */
3596 if (!ins_rc[0] && fileObj[0]) {
3597 PyDict_DelItem(_PyPopenProcs,
3598 fileObj[0]);
3599 }
3600 if (!ins_rc[1] && fileObj[1]) {
3601 PyDict_DelItem(_PyPopenProcs,
3602 fileObj[1]);
3603 }
3604 if (!ins_rc[2] && fileObj[2]) {
3605 PyDict_DelItem(_PyPopenProcs,
3606 fileObj[2]);
3607 }
3608 }
3609 }
Tim Peters5aa91602002-01-30 05:46:57 +00003610
Mark Hammondb37a3732000-08-14 04:47:33 +00003611 /*
3612 * Clean up our localized references for the dictionary keys
3613 * and value since PyDict_SetItem will Py_INCREF any copies
3614 * that got placed in the dictionary.
3615 */
3616 Py_XDECREF(procObj);
3617 Py_XDECREF(fileObj[0]);
3618 Py_XDECREF(fileObj[1]);
3619 Py_XDECREF(fileObj[2]);
3620 }
3621
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003622 /* Child is launched. Close the parents copy of those pipe
3623 * handles that only the child should have open. You need to
3624 * make sure that no handles to the write end of the output pipe
3625 * are maintained in this process or else the pipe will not close
3626 * when the child process exits and the ReadFile will hang. */
3627
3628 if (!CloseHandle(hChildStdinRd))
3629 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003630
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003631 if (!CloseHandle(hChildStdoutWr))
3632 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003633
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003634 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3635 return win32_error("CloseHandle", NULL);
3636
3637 return f;
3638}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003639
3640/*
3641 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3642 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003643 *
3644 * This function uses the _PyPopenProcs dictionary in order to map the
3645 * input file pointer to information about the process that was
3646 * originally created by the popen* call that created the file pointer.
3647 * The dictionary uses the file pointer as a key (with one entry
3648 * inserted for each file returned by the original popen* call) and a
3649 * single list object as the value for all files from a single call.
3650 * The list object contains the Win32 process handle at [0], and a file
3651 * count at [1], which is initialized to the total number of file
3652 * handles using that list.
3653 *
3654 * This function closes whichever handle it is passed, and decrements
3655 * the file count in the dictionary for the process handle pointed to
3656 * by this file. On the last close (when the file count reaches zero),
3657 * this function will wait for the child process and then return its
3658 * exit code as the result of the close() operation. This permits the
3659 * files to be closed in any order - it is always the close() of the
3660 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003661 */
Tim Peters736aa322000-09-01 06:51:24 +00003662
3663 /* RED_FLAG 31-Aug-2000 Tim
3664 * This is always called (today!) between a pair of
3665 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3666 * macros. So the thread running this has no valid thread state, as
3667 * far as Python is concerned. However, this calls some Python API
3668 * functions that cannot be called safely without a valid thread
3669 * state, in particular PyDict_GetItem.
3670 * As a temporary hack (although it may last for years ...), we
3671 * *rely* on not having a valid thread state in this function, in
3672 * order to create our own "from scratch".
3673 * This will deadlock if _PyPclose is ever called by a thread
3674 * holding the global lock.
3675 */
3676
Fredrik Lundh56055a42000-07-23 19:47:12 +00003677static int _PyPclose(FILE *file)
3678{
Fredrik Lundh20318932000-07-26 17:29:12 +00003679 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003680 DWORD exit_code;
3681 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003682 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3683 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003684#ifdef WITH_THREAD
3685 PyInterpreterState* pInterpreterState;
3686 PyThreadState* pThreadState;
3687#endif
3688
Fredrik Lundh20318932000-07-26 17:29:12 +00003689 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003690 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003691 */
3692 result = fclose(file);
3693
Tim Peters736aa322000-09-01 06:51:24 +00003694#ifdef WITH_THREAD
3695 /* Bootstrap a valid thread state into existence. */
3696 pInterpreterState = PyInterpreterState_New();
3697 if (!pInterpreterState) {
3698 /* Well, we're hosed now! We don't have a thread
3699 * state, so can't call a nice error routine, or raise
3700 * an exception. Just die.
3701 */
3702 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003703 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003704 return -1; /* unreachable */
3705 }
3706 pThreadState = PyThreadState_New(pInterpreterState);
3707 if (!pThreadState) {
3708 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003709 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003710 return -1; /* unreachable */
3711 }
3712 /* Grab the global lock. Note that this will deadlock if the
3713 * current thread already has the lock! (see RED_FLAG comments
3714 * before this function)
3715 */
3716 PyEval_RestoreThread(pThreadState);
3717#endif
3718
Fredrik Lundh56055a42000-07-23 19:47:12 +00003719 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003720 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3721 (procObj = PyDict_GetItem(_PyPopenProcs,
3722 fileObj)) != NULL &&
3723 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3724 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3725
3726 hProcess = PyLong_AsVoidPtr(hProcessObj);
3727 file_count = PyInt_AsLong(intObj);
3728
3729 if (file_count > 1) {
3730 /* Still other files referencing process */
3731 file_count--;
3732 PyList_SetItem(procObj,1,
3733 PyInt_FromLong(file_count));
3734 } else {
3735 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003736 if (result != EOF &&
3737 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3738 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003739 /* Possible truncation here in 16-bit environments, but
3740 * real exit codes are just the lower byte in any event.
3741 */
3742 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003743 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003744 /* Indicate failure - this will cause the file object
3745 * to raise an I/O error and translate the last Win32
3746 * error code from errno. We do have a problem with
3747 * last errors that overlap the normal errno table,
3748 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003749 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003750 if (result != EOF) {
3751 /* If the error wasn't from the fclose(), then
3752 * set errno for the file object error handling.
3753 */
3754 errno = GetLastError();
3755 }
3756 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003757 }
3758
3759 /* Free up the native handle at this point */
3760 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003761 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003762
Mark Hammondb37a3732000-08-14 04:47:33 +00003763 /* Remove this file pointer from dictionary */
3764 PyDict_DelItem(_PyPopenProcs, fileObj);
3765
3766 if (PyDict_Size(_PyPopenProcs) == 0) {
3767 Py_DECREF(_PyPopenProcs);
3768 _PyPopenProcs = NULL;
3769 }
3770
3771 } /* if object retrieval ok */
3772
3773 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003774 } /* if _PyPopenProcs */
3775
Tim Peters736aa322000-09-01 06:51:24 +00003776#ifdef WITH_THREAD
3777 /* Tear down the thread & interpreter states.
3778 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003779 * call the thread clear & delete functions, and indeed insist on
3780 * doing that themselves. The lock must be held during the clear, but
3781 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003782 */
3783 PyInterpreterState_Clear(pInterpreterState);
3784 PyEval_ReleaseThread(pThreadState);
3785 PyInterpreterState_Delete(pInterpreterState);
3786#endif
3787
Fredrik Lundh56055a42000-07-23 19:47:12 +00003788 return result;
3789}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003790
3791#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003793posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003794{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003795 char *name;
3796 char *mode = "r";
3797 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003798 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003799 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003800 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003801 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003802 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003803 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003804 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003805 if (fp == NULL)
3806 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003807 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003808 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003809 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003810 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003811}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003812
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003813#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003814#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003815
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003816
Guido van Rossumb6775db1994-08-01 11:34:53 +00003817#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003818PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003819"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003820Set the current process's user id.");
3821
Barry Warsaw53699e91996-12-10 23:23:01 +00003822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003823posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003824{
3825 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003826 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003827 return NULL;
3828 if (setuid(uid) < 0)
3829 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003830 Py_INCREF(Py_None);
3831 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003832}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003833#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003834
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003835
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003836#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003837PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003838"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003839Set the current process's effective user id.");
3840
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003841static PyObject *
3842posix_seteuid (PyObject *self, PyObject *args)
3843{
3844 int euid;
3845 if (!PyArg_ParseTuple(args, "i", &euid)) {
3846 return NULL;
3847 } else if (seteuid(euid) < 0) {
3848 return posix_error();
3849 } else {
3850 Py_INCREF(Py_None);
3851 return Py_None;
3852 }
3853}
3854#endif /* HAVE_SETEUID */
3855
3856#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003857PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003858"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003859Set the current process's effective group id.");
3860
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003861static PyObject *
3862posix_setegid (PyObject *self, PyObject *args)
3863{
3864 int egid;
3865 if (!PyArg_ParseTuple(args, "i", &egid)) {
3866 return NULL;
3867 } else if (setegid(egid) < 0) {
3868 return posix_error();
3869 } else {
3870 Py_INCREF(Py_None);
3871 return Py_None;
3872 }
3873}
3874#endif /* HAVE_SETEGID */
3875
3876#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003877PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003878"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003879Set the current process's real and effective user ids.");
3880
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003881static PyObject *
3882posix_setreuid (PyObject *self, PyObject *args)
3883{
3884 int ruid, euid;
3885 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3886 return NULL;
3887 } else if (setreuid(ruid, euid) < 0) {
3888 return posix_error();
3889 } else {
3890 Py_INCREF(Py_None);
3891 return Py_None;
3892 }
3893}
3894#endif /* HAVE_SETREUID */
3895
3896#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003897PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003898"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003899Set the current process's real and effective group ids.");
3900
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003901static PyObject *
3902posix_setregid (PyObject *self, PyObject *args)
3903{
3904 int rgid, egid;
3905 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3906 return NULL;
3907 } else if (setregid(rgid, egid) < 0) {
3908 return posix_error();
3909 } else {
3910 Py_INCREF(Py_None);
3911 return Py_None;
3912 }
3913}
3914#endif /* HAVE_SETREGID */
3915
Guido van Rossumb6775db1994-08-01 11:34:53 +00003916#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003917PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003918"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003919Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003920
Barry Warsaw53699e91996-12-10 23:23:01 +00003921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003922posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003923{
3924 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003925 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003926 return NULL;
3927 if (setgid(gid) < 0)
3928 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003929 Py_INCREF(Py_None);
3930 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003931}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003932#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003933
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003934#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003935PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003936"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003937Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003938
3939static PyObject *
3940posix_setgroups(PyObject *self, PyObject *args)
3941{
3942 PyObject *groups;
3943 int i, len;
3944 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003945
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003946 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3947 return NULL;
3948 if (!PySequence_Check(groups)) {
3949 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3950 return NULL;
3951 }
3952 len = PySequence_Size(groups);
3953 if (len > MAX_GROUPS) {
3954 PyErr_SetString(PyExc_ValueError, "too many groups");
3955 return NULL;
3956 }
3957 for(i = 0; i < len; i++) {
3958 PyObject *elem;
3959 elem = PySequence_GetItem(groups, i);
3960 if (!elem)
3961 return NULL;
3962 if (!PyInt_Check(elem)) {
3963 PyErr_SetString(PyExc_TypeError,
3964 "groups must be integers");
3965 Py_DECREF(elem);
3966 return NULL;
3967 }
3968 /* XXX: check that value fits into gid_t. */
3969 grouplist[i] = PyInt_AsLong(elem);
3970 Py_DECREF(elem);
3971 }
3972
3973 if (setgroups(len, grouplist) < 0)
3974 return posix_error();
3975 Py_INCREF(Py_None);
3976 return Py_None;
3977}
3978#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003979
Guido van Rossumb6775db1994-08-01 11:34:53 +00003980#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003981PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003982"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003983Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003984
Barry Warsaw53699e91996-12-10 23:23:01 +00003985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003986posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003987{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003988 int pid, options;
3989#ifdef UNION_WAIT
3990 union wait status;
3991#define status_i (status.w_status)
3992#else
3993 int status;
3994#define status_i status
3995#endif
3996 status_i = 0;
3997
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003998 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003999 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004000 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004001 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004002 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004003 if (pid == -1)
4004 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004005 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004006 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004007}
4008
Tim Petersab034fa2002-02-01 11:27:43 +00004009#elif defined(HAVE_CWAIT)
4010
4011/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004012PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004013"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004014"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004015
4016static PyObject *
4017posix_waitpid(PyObject *self, PyObject *args)
4018{
4019 int pid, options;
4020 int status;
4021
4022 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4023 return NULL;
4024 Py_BEGIN_ALLOW_THREADS
4025 pid = _cwait(&status, pid, options);
4026 Py_END_ALLOW_THREADS
4027 if (pid == -1)
4028 return posix_error();
4029 else
4030 /* shift the status left a byte so this is more like the
4031 POSIX waitpid */
4032 return Py_BuildValue("ii", pid, status << 8);
4033}
4034#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004035
Guido van Rossumad0ee831995-03-01 10:34:45 +00004036#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004037PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004038"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004039Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004040
Barry Warsaw53699e91996-12-10 23:23:01 +00004041static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004042posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004043{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004044 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004045#ifdef UNION_WAIT
4046 union wait status;
4047#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004048#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004049 int status;
4050#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004051#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004052 if (!PyArg_ParseTuple(args, ":wait"))
4053 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004054 status_i = 0;
4055 Py_BEGIN_ALLOW_THREADS
4056 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004057 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004058 if (pid == -1)
4059 return posix_error();
4060 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004061 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004062#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004063}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004064#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004066
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004067PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004068"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004069Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004070
Barry Warsaw53699e91996-12-10 23:23:01 +00004071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004072posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004073{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004074#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004075 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004076#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004077 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004078#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004079}
4080
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004081
Guido van Rossumb6775db1994-08-01 11:34:53 +00004082#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004083PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004084"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004085Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004086
Barry Warsaw53699e91996-12-10 23:23:01 +00004087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004088posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004089{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004090 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004091 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004092 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004093 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004094 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004095 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004096 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004097 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004098 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004099 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004100 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004101}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004102#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004103
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004104
Guido van Rossumb6775db1994-08-01 11:34:53 +00004105#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004106PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004107"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004108Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004109
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004111posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004112{
Mark Hammondef8b6542001-05-13 08:04:26 +00004113 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004114}
4115#endif /* HAVE_SYMLINK */
4116
4117
4118#ifdef HAVE_TIMES
4119#ifndef HZ
4120#define HZ 60 /* Universal constant :-) */
4121#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004122
Guido van Rossumd48f2521997-12-05 22:19:34 +00004123#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4124static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004125system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004126{
4127 ULONG value = 0;
4128
4129 Py_BEGIN_ALLOW_THREADS
4130 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4131 Py_END_ALLOW_THREADS
4132
4133 return value;
4134}
4135
4136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004137posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004138{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004139 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004140 return NULL;
4141
4142 /* Currently Only Uptime is Provided -- Others Later */
4143 return Py_BuildValue("ddddd",
4144 (double)0 /* t.tms_utime / HZ */,
4145 (double)0 /* t.tms_stime / HZ */,
4146 (double)0 /* t.tms_cutime / HZ */,
4147 (double)0 /* t.tms_cstime / HZ */,
4148 (double)system_uptime() / 1000);
4149}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004150#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004152posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004153{
4154 struct tms t;
4155 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004156 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004157 return NULL;
4158 errno = 0;
4159 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004160 if (c == (clock_t) -1)
4161 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004162 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004163 (double)t.tms_utime / HZ,
4164 (double)t.tms_stime / HZ,
4165 (double)t.tms_cutime / HZ,
4166 (double)t.tms_cstime / HZ,
4167 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004168}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004169#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004170#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004171
4172
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004173#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004174#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004176posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004177{
4178 FILETIME create, exit, kernel, user;
4179 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004180 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004181 return NULL;
4182 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004183 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4184 /* The fields of a FILETIME structure are the hi and lo part
4185 of a 64-bit value expressed in 100 nanosecond units.
4186 1e7 is one second in such units; 1e-7 the inverse.
4187 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4188 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004189 return Py_BuildValue(
4190 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004191 (double)(kernel.dwHighDateTime*429.4967296 +
4192 kernel.dwLowDateTime*1e-7),
4193 (double)(user.dwHighDateTime*429.4967296 +
4194 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004195 (double)0,
4196 (double)0,
4197 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004198}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004199#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004200
4201#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004202PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004203"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004204Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004205#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004207
Guido van Rossumb6775db1994-08-01 11:34:53 +00004208#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004209PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004210"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004211Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004212
Barry Warsaw53699e91996-12-10 23:23:01 +00004213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004214posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004215{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004216 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004217 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004218 if (setsid() < 0)
4219 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004220 Py_INCREF(Py_None);
4221 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004222}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004223#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004224
Guido van Rossumb6775db1994-08-01 11:34:53 +00004225#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004226PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004227"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004228Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004229
Barry Warsaw53699e91996-12-10 23:23:01 +00004230static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004231posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004232{
4233 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004234 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004235 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004236 if (setpgid(pid, pgrp) < 0)
4237 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004238 Py_INCREF(Py_None);
4239 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004240}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004241#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004243
Guido van Rossumb6775db1994-08-01 11:34:53 +00004244#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004245PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004246"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004247Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004248
Barry Warsaw53699e91996-12-10 23:23:01 +00004249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004250posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004251{
4252 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004253 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004254 return NULL;
4255 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004256 if (pgid < 0)
4257 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004258 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004259}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004260#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004262
Guido van Rossumb6775db1994-08-01 11:34:53 +00004263#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004264PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004265"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004266Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004267
Barry Warsaw53699e91996-12-10 23:23:01 +00004268static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004269posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004270{
4271 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004272 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004273 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004274 if (tcsetpgrp(fd, pgid) < 0)
4275 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004276 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004277 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004278}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004279#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004280
Guido van Rossum687dd131993-05-17 08:34:16 +00004281/* Functions acting on file descriptors */
4282
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004283PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004284"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004285Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004286
Barry Warsaw53699e91996-12-10 23:23:01 +00004287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004288posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004289{
Mark Hammondef8b6542001-05-13 08:04:26 +00004290 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004291 int flag;
4292 int mode = 0777;
4293 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004294 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004295 Py_FileSystemDefaultEncoding, &file,
4296 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004297 return NULL;
4298
Barry Warsaw53699e91996-12-10 23:23:01 +00004299 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004300 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004301 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004302 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004303 return posix_error_with_allocated_filename(file);
4304 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004305 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004306}
4307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004308
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004309PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004310"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004311Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004312
Barry Warsaw53699e91996-12-10 23:23:01 +00004313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004314posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004315{
4316 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004317 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004318 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004319 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004320 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004321 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004322 if (res < 0)
4323 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004324 Py_INCREF(Py_None);
4325 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004326}
4327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004329PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004330"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004331Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004332
Barry Warsaw53699e91996-12-10 23:23:01 +00004333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004334posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004335{
4336 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004337 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004338 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004339 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004340 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004341 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004342 if (fd < 0)
4343 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004344 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004345}
4346
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004347
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004348PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004349"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004350Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004351
Barry Warsaw53699e91996-12-10 23:23:01 +00004352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004353posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004354{
4355 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004356 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004357 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004358 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004359 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004360 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004361 if (res < 0)
4362 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004363 Py_INCREF(Py_None);
4364 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004365}
4366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004368PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004369"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004370Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004371
Barry Warsaw53699e91996-12-10 23:23:01 +00004372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004373posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004374{
4375 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004376#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004377 LONG_LONG pos, res;
4378#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004379 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004380#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004381 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004382 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004383 return NULL;
4384#ifdef SEEK_SET
4385 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4386 switch (how) {
4387 case 0: how = SEEK_SET; break;
4388 case 1: how = SEEK_CUR; break;
4389 case 2: how = SEEK_END; break;
4390 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004391#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004392
4393#if !defined(HAVE_LARGEFILE_SUPPORT)
4394 pos = PyInt_AsLong(posobj);
4395#else
4396 pos = PyLong_Check(posobj) ?
4397 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4398#endif
4399 if (PyErr_Occurred())
4400 return NULL;
4401
Barry Warsaw53699e91996-12-10 23:23:01 +00004402 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004403#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004404 res = _lseeki64(fd, pos, how);
4405#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004406 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004407#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004408 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004409 if (res < 0)
4410 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004411
4412#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004413 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004414#else
4415 return PyLong_FromLongLong(res);
4416#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004417}
4418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004419
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004420PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004421"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004422Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004423
Barry Warsaw53699e91996-12-10 23:23:01 +00004424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004425posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004426{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004427 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004428 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004429 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004430 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004431 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004432 if (buffer == NULL)
4433 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004434 Py_BEGIN_ALLOW_THREADS
4435 n = read(fd, PyString_AsString(buffer), size);
4436 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004437 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004438 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004439 return posix_error();
4440 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004441 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004442 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004443 return buffer;
4444}
4445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004446
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004447PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004448"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004449Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004450
Barry Warsaw53699e91996-12-10 23:23:01 +00004451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004452posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004453{
4454 int fd, size;
4455 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004456 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004457 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004458 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004459 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004460 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004461 if (size < 0)
4462 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004463 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004464}
4465
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004467PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004468"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004469Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004470
Barry Warsaw53699e91996-12-10 23:23:01 +00004471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004472posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004473{
4474 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004475 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004476 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004477 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004478 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004479 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004480 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004481 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004482 if (res != 0)
4483 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004484
Fred Drake699f3522000-06-29 21:12:41 +00004485 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004486}
4487
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004489PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004490"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004491Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004492
Barry Warsaw53699e91996-12-10 23:23:01 +00004493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004494posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004495{
Guido van Rossum687dd131993-05-17 08:34:16 +00004496 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004497 char *mode = "r";
4498 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004499 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004500 PyObject *f;
4501 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004502 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004503
Barry Warsaw53699e91996-12-10 23:23:01 +00004504 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004505 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004506 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004507 if (fp == NULL)
4508 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004509 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004510 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004511 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004512 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004513}
4514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004515PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004516"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004517Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004518connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004519
4520static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004521posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004522{
4523 int fd;
4524 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4525 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004526 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004527}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004528
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004529#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004530PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004531"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004532Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004533
Barry Warsaw53699e91996-12-10 23:23:01 +00004534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004535posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004536{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004537#if defined(PYOS_OS2)
4538 HFILE read, write;
4539 APIRET rc;
4540
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004541 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004542 return NULL;
4543
4544 Py_BEGIN_ALLOW_THREADS
4545 rc = DosCreatePipe( &read, &write, 4096);
4546 Py_END_ALLOW_THREADS
4547 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004548 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004549
4550 return Py_BuildValue("(ii)", read, write);
4551#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004552#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004553 int fds[2];
4554 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004555 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004556 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004557 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004558 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004559 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004560 if (res != 0)
4561 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004562 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004563#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004564 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004565 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004566 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004567 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004568 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004569 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004570 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004571 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004572 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004573 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004574 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4575 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004576 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004577#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004578#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004579}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004580#endif /* HAVE_PIPE */
4581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004582
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004583#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004584PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004585"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004586Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004587
Barry Warsaw53699e91996-12-10 23:23:01 +00004588static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004589posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004590{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004591 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004592 int mode = 0666;
4593 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004594 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004595 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004596 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004597 res = mkfifo(filename, mode);
4598 Py_END_ALLOW_THREADS
4599 if (res < 0)
4600 return posix_error();
4601 Py_INCREF(Py_None);
4602 return Py_None;
4603}
4604#endif
4605
4606
Neal Norwitz11690112002-07-30 01:08:28 +00004607#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004608PyDoc_STRVAR(posix_mknod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004609"mknod(filename, [, mode=0600, major, minor])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004610Create a filesystem node (file, device special file or named pipe)\n\
4611named filename. mode specifies both the permissions to use and the\n\
4612type of node to be created, being combined (bitwise OR) with one of\n\
4613S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4614major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004615they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004616
4617
4618static PyObject *
4619posix_mknod(PyObject *self, PyObject *args)
4620{
4621 char *filename;
4622 int mode = 0600;
4623 int major = 0;
4624 int minor = 0;
4625 int res;
4626 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4627 &mode, &major, &minor))
4628 return NULL;
4629 Py_BEGIN_ALLOW_THREADS
4630 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004631 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004632 if (res < 0)
4633 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004634 Py_INCREF(Py_None);
4635 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004636}
4637#endif
4638
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004639
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004640#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004641PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004642"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004643Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004644
Barry Warsaw53699e91996-12-10 23:23:01 +00004645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004646posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004647{
4648 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004649 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004650 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004651 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004652
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004653 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004654 return NULL;
4655
4656#if !defined(HAVE_LARGEFILE_SUPPORT)
4657 length = PyInt_AsLong(lenobj);
4658#else
4659 length = PyLong_Check(lenobj) ?
4660 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4661#endif
4662 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004663 return NULL;
4664
Barry Warsaw53699e91996-12-10 23:23:01 +00004665 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004666 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004667 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004668 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004669 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004670 return NULL;
4671 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004672 Py_INCREF(Py_None);
4673 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004674}
4675#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004676
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004677#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004678PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004679"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004680Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004681
Fred Drake762e2061999-08-26 17:23:54 +00004682/* Save putenv() parameters as values here, so we can collect them when they
4683 * get re-set with another call for the same key. */
4684static PyObject *posix_putenv_garbage;
4685
Tim Peters5aa91602002-01-30 05:46:57 +00004686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004687posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004688{
4689 char *s1, *s2;
4690 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004691 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004692 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004693
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004694 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004695 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004696
4697#if defined(PYOS_OS2)
4698 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4699 APIRET rc;
4700
4701 if (strlen(s2) == 0) /* If New Value is an Empty String */
4702 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4703
4704 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4705 if (rc != NO_ERROR)
4706 return os2_error(rc);
4707
4708 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4709 APIRET rc;
4710
4711 if (strlen(s2) == 0) /* If New Value is an Empty String */
4712 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4713
4714 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4715 if (rc != NO_ERROR)
4716 return os2_error(rc);
4717 } else {
4718#endif
4719
Fred Drake762e2061999-08-26 17:23:54 +00004720 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004721 len = strlen(s1) + strlen(s2) + 2;
4722 /* len includes space for a trailing \0; the size arg to
4723 PyString_FromStringAndSize does not count that */
4724 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004725 if (newstr == NULL)
4726 return PyErr_NoMemory();
4727 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004728 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004729 if (putenv(new)) {
4730 posix_error();
4731 return NULL;
4732 }
Fred Drake762e2061999-08-26 17:23:54 +00004733 /* Install the first arg and newstr in posix_putenv_garbage;
4734 * this will cause previous value to be collected. This has to
4735 * happen after the real putenv() call because the old value
4736 * was still accessible until then. */
4737 if (PyDict_SetItem(posix_putenv_garbage,
4738 PyTuple_GET_ITEM(args, 0), newstr)) {
4739 /* really not much we can do; just leak */
4740 PyErr_Clear();
4741 }
4742 else {
4743 Py_DECREF(newstr);
4744 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004745
4746#if defined(PYOS_OS2)
4747 }
4748#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004749 Py_INCREF(Py_None);
4750 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004751}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004752#endif /* putenv */
4753
Guido van Rossumc524d952001-10-19 01:31:59 +00004754#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004755PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004756"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004757Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00004758
4759static PyObject *
4760posix_unsetenv(PyObject *self, PyObject *args)
4761{
4762 char *s1;
4763
4764 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4765 return NULL;
4766
4767 unsetenv(s1);
4768
4769 /* Remove the key from posix_putenv_garbage;
4770 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004771 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004772 * old value was still accessible until then.
4773 */
4774 if (PyDict_DelItem(posix_putenv_garbage,
4775 PyTuple_GET_ITEM(args, 0))) {
4776 /* really not much we can do; just leak */
4777 PyErr_Clear();
4778 }
4779
4780 Py_INCREF(Py_None);
4781 return Py_None;
4782}
4783#endif /* unsetenv */
4784
Guido van Rossumb6a47161997-09-15 22:54:34 +00004785#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004786PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004787"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004788Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004789
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004791posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004792{
4793 int code;
4794 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004795 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004796 return NULL;
4797 message = strerror(code);
4798 if (message == NULL) {
4799 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004800 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004801 return NULL;
4802 }
4803 return PyString_FromString(message);
4804}
4805#endif /* strerror */
4806
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004807
Guido van Rossumc9641791998-08-04 15:26:23 +00004808#ifdef HAVE_SYS_WAIT_H
4809
Fred Drake106c1a02002-04-23 15:58:02 +00004810#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004811PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004812"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004813Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00004814
4815static PyObject *
4816posix_WCOREDUMP(PyObject *self, PyObject *args)
4817{
4818#ifdef UNION_WAIT
4819 union wait status;
4820#define status_i (status.w_status)
4821#else
4822 int status;
4823#define status_i status
4824#endif
4825 status_i = 0;
4826
4827 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4828 {
4829 return NULL;
4830 }
4831
4832 return PyBool_FromLong(WCOREDUMP(status));
4833#undef status_i
4834}
4835#endif /* WCOREDUMP */
4836
4837#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004838PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004839"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004840Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004841job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00004842
4843static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004844posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004845{
4846#ifdef UNION_WAIT
4847 union wait status;
4848#define status_i (status.w_status)
4849#else
4850 int status;
4851#define status_i status
4852#endif
4853 status_i = 0;
4854
4855 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4856 {
4857 return NULL;
4858 }
4859
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004860 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004861#undef status_i
4862}
4863#endif /* WIFCONTINUED */
4864
Guido van Rossumc9641791998-08-04 15:26:23 +00004865#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004866PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004867"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004868Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004869
4870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004871posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004872{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004873#ifdef UNION_WAIT
4874 union wait status;
4875#define status_i (status.w_status)
4876#else
4877 int status;
4878#define status_i status
4879#endif
4880 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004881
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004882 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004883 {
4884 return NULL;
4885 }
Tim Peters5aa91602002-01-30 05:46:57 +00004886
Fred Drake106c1a02002-04-23 15:58:02 +00004887 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004888#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004889}
4890#endif /* WIFSTOPPED */
4891
4892#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004893PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004894"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004895Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004896
4897static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004898posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004899{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004900#ifdef UNION_WAIT
4901 union wait status;
4902#define status_i (status.w_status)
4903#else
4904 int status;
4905#define status_i status
4906#endif
4907 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004908
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004909 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004910 {
4911 return NULL;
4912 }
Tim Peters5aa91602002-01-30 05:46:57 +00004913
Fred Drake106c1a02002-04-23 15:58:02 +00004914 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004915#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004916}
4917#endif /* WIFSIGNALED */
4918
4919#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004920PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004921"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004922Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004923system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004924
4925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004926posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004927{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004928#ifdef UNION_WAIT
4929 union wait status;
4930#define status_i (status.w_status)
4931#else
4932 int status;
4933#define status_i status
4934#endif
4935 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004936
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004937 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004938 {
4939 return NULL;
4940 }
Tim Peters5aa91602002-01-30 05:46:57 +00004941
Fred Drake106c1a02002-04-23 15:58:02 +00004942 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004943#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004944}
4945#endif /* WIFEXITED */
4946
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004947#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004948PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004949"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004950Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004951
4952static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004953posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004954{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004955#ifdef UNION_WAIT
4956 union wait status;
4957#define status_i (status.w_status)
4958#else
4959 int status;
4960#define status_i status
4961#endif
4962 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004963
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004964 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004965 {
4966 return NULL;
4967 }
Tim Peters5aa91602002-01-30 05:46:57 +00004968
Guido van Rossumc9641791998-08-04 15:26:23 +00004969 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004970#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004971}
4972#endif /* WEXITSTATUS */
4973
4974#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004975PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004976"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004977Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004978value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004979
4980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004981posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004982{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004983#ifdef UNION_WAIT
4984 union wait status;
4985#define status_i (status.w_status)
4986#else
4987 int status;
4988#define status_i status
4989#endif
4990 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004991
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004992 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004993 {
4994 return NULL;
4995 }
Tim Peters5aa91602002-01-30 05:46:57 +00004996
Guido van Rossumc9641791998-08-04 15:26:23 +00004997 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004998#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004999}
5000#endif /* WTERMSIG */
5001
5002#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005003PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005004"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005005Return the signal that stopped the process that provided\n\
5006the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005007
5008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005009posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005010{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005011#ifdef UNION_WAIT
5012 union wait status;
5013#define status_i (status.w_status)
5014#else
5015 int status;
5016#define status_i status
5017#endif
5018 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005019
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005020 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005021 {
5022 return NULL;
5023 }
Tim Peters5aa91602002-01-30 05:46:57 +00005024
Guido van Rossumc9641791998-08-04 15:26:23 +00005025 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005026#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005027}
5028#endif /* WSTOPSIG */
5029
5030#endif /* HAVE_SYS_WAIT_H */
5031
5032
Guido van Rossum94f6f721999-01-06 18:42:14 +00005033#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005034#ifdef _SCO_DS
5035/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5036 needed definitions in sys/statvfs.h */
5037#define _SVID3
5038#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005039#include <sys/statvfs.h>
5040
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005041static PyObject*
5042_pystatvfs_fromstructstatvfs(struct statvfs st) {
5043 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5044 if (v == NULL)
5045 return NULL;
5046
5047#if !defined(HAVE_LARGEFILE_SUPPORT)
5048 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5049 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5050 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5051 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5052 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5053 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5054 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5055 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5056 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5057 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5058#else
5059 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5060 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005061 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005062 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005063 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005064 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5065 PyStructSequence_SET_ITEM(v, 4,
5066 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005067 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005068 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005069 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005070 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005071 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005072 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5073 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5074 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5075#endif
5076
5077 return v;
5078}
5079
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005080PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005081"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005082Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005083
5084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005085posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005086{
5087 int fd, res;
5088 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005089
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005090 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005091 return NULL;
5092 Py_BEGIN_ALLOW_THREADS
5093 res = fstatvfs(fd, &st);
5094 Py_END_ALLOW_THREADS
5095 if (res != 0)
5096 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005097
5098 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005099}
5100#endif /* HAVE_FSTATVFS */
5101
5102
5103#if defined(HAVE_STATVFS)
5104#include <sys/statvfs.h>
5105
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005106PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005107"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005108Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005109
5110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005111posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005112{
5113 char *path;
5114 int res;
5115 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005116 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005117 return NULL;
5118 Py_BEGIN_ALLOW_THREADS
5119 res = statvfs(path, &st);
5120 Py_END_ALLOW_THREADS
5121 if (res != 0)
5122 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005123
5124 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005125}
5126#endif /* HAVE_STATVFS */
5127
5128
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005129#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005130PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005131"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005132Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005133The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005134or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005135
5136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005137posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005138{
5139 PyObject *result = NULL;
5140 char *dir = NULL;
5141 char *pfx = NULL;
5142 char *name;
5143
5144 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5145 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005146
5147 if (PyErr_Warn(PyExc_RuntimeWarning,
5148 "tempnam is a potential security risk to your program") < 0)
5149 return NULL;
5150
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005151#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005152 name = _tempnam(dir, pfx);
5153#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005154 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005155#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005156 if (name == NULL)
5157 return PyErr_NoMemory();
5158 result = PyString_FromString(name);
5159 free(name);
5160 return result;
5161}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005162#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005163
5164
5165#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005166PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005167"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005168Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005169
5170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005171posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005172{
5173 FILE *fp;
5174
5175 if (!PyArg_ParseTuple(args, ":tmpfile"))
5176 return NULL;
5177 fp = tmpfile();
5178 if (fp == NULL)
5179 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005180 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005181}
5182#endif
5183
5184
5185#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005186PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005187"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005188Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005189
5190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005191posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005192{
5193 char buffer[L_tmpnam];
5194 char *name;
5195
5196 if (!PyArg_ParseTuple(args, ":tmpnam"))
5197 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005198
5199 if (PyErr_Warn(PyExc_RuntimeWarning,
5200 "tmpnam is a potential security risk to your program") < 0)
5201 return NULL;
5202
Greg Wardb48bc172000-03-01 21:51:56 +00005203#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005204 name = tmpnam_r(buffer);
5205#else
5206 name = tmpnam(buffer);
5207#endif
5208 if (name == NULL) {
5209 PyErr_SetObject(PyExc_OSError,
5210 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005211#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005212 "unexpected NULL from tmpnam_r"
5213#else
5214 "unexpected NULL from tmpnam"
5215#endif
5216 ));
5217 return NULL;
5218 }
5219 return PyString_FromString(buffer);
5220}
5221#endif
5222
5223
Fred Drakec9680921999-12-13 16:37:25 +00005224/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5225 * It maps strings representing configuration variable names to
5226 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005227 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005228 * rarely-used constants. There are three separate tables that use
5229 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005230 *
5231 * This code is always included, even if none of the interfaces that
5232 * need it are included. The #if hackery needed to avoid it would be
5233 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005234 */
5235struct constdef {
5236 char *name;
5237 long value;
5238};
5239
Fred Drake12c6e2d1999-12-14 21:25:03 +00005240static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005241conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5242 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005243{
5244 if (PyInt_Check(arg)) {
5245 *valuep = PyInt_AS_LONG(arg);
5246 return 1;
5247 }
5248 if (PyString_Check(arg)) {
5249 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005250 size_t lo = 0;
5251 size_t mid;
5252 size_t hi = tablesize;
5253 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005254 char *confname = PyString_AS_STRING(arg);
5255 while (lo < hi) {
5256 mid = (lo + hi) / 2;
5257 cmp = strcmp(confname, table[mid].name);
5258 if (cmp < 0)
5259 hi = mid;
5260 else if (cmp > 0)
5261 lo = mid + 1;
5262 else {
5263 *valuep = table[mid].value;
5264 return 1;
5265 }
5266 }
5267 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5268 }
5269 else
5270 PyErr_SetString(PyExc_TypeError,
5271 "configuration names must be strings or integers");
5272 return 0;
5273}
5274
5275
5276#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5277static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005278#ifdef _PC_ABI_AIO_XFER_MAX
5279 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5280#endif
5281#ifdef _PC_ABI_ASYNC_IO
5282 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5283#endif
Fred Drakec9680921999-12-13 16:37:25 +00005284#ifdef _PC_ASYNC_IO
5285 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5286#endif
5287#ifdef _PC_CHOWN_RESTRICTED
5288 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5289#endif
5290#ifdef _PC_FILESIZEBITS
5291 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5292#endif
5293#ifdef _PC_LAST
5294 {"PC_LAST", _PC_LAST},
5295#endif
5296#ifdef _PC_LINK_MAX
5297 {"PC_LINK_MAX", _PC_LINK_MAX},
5298#endif
5299#ifdef _PC_MAX_CANON
5300 {"PC_MAX_CANON", _PC_MAX_CANON},
5301#endif
5302#ifdef _PC_MAX_INPUT
5303 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5304#endif
5305#ifdef _PC_NAME_MAX
5306 {"PC_NAME_MAX", _PC_NAME_MAX},
5307#endif
5308#ifdef _PC_NO_TRUNC
5309 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5310#endif
5311#ifdef _PC_PATH_MAX
5312 {"PC_PATH_MAX", _PC_PATH_MAX},
5313#endif
5314#ifdef _PC_PIPE_BUF
5315 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5316#endif
5317#ifdef _PC_PRIO_IO
5318 {"PC_PRIO_IO", _PC_PRIO_IO},
5319#endif
5320#ifdef _PC_SOCK_MAXBUF
5321 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5322#endif
5323#ifdef _PC_SYNC_IO
5324 {"PC_SYNC_IO", _PC_SYNC_IO},
5325#endif
5326#ifdef _PC_VDISABLE
5327 {"PC_VDISABLE", _PC_VDISABLE},
5328#endif
5329};
5330
Fred Drakec9680921999-12-13 16:37:25 +00005331static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005332conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005333{
5334 return conv_confname(arg, valuep, posix_constants_pathconf,
5335 sizeof(posix_constants_pathconf)
5336 / sizeof(struct constdef));
5337}
5338#endif
5339
5340#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005341PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005342"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005343Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005344If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005345
5346static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005347posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005348{
5349 PyObject *result = NULL;
5350 int name, fd;
5351
Fred Drake12c6e2d1999-12-14 21:25:03 +00005352 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5353 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005354 long limit;
5355
5356 errno = 0;
5357 limit = fpathconf(fd, name);
5358 if (limit == -1 && errno != 0)
5359 posix_error();
5360 else
5361 result = PyInt_FromLong(limit);
5362 }
5363 return result;
5364}
5365#endif
5366
5367
5368#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005369PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005370"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005371Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005372If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005373
5374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005375posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005376{
5377 PyObject *result = NULL;
5378 int name;
5379 char *path;
5380
5381 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5382 conv_path_confname, &name)) {
5383 long limit;
5384
5385 errno = 0;
5386 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005387 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005388 if (errno == EINVAL)
5389 /* could be a path or name problem */
5390 posix_error();
5391 else
5392 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005393 }
Fred Drakec9680921999-12-13 16:37:25 +00005394 else
5395 result = PyInt_FromLong(limit);
5396 }
5397 return result;
5398}
5399#endif
5400
5401#ifdef HAVE_CONFSTR
5402static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005403#ifdef _CS_ARCHITECTURE
5404 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5405#endif
5406#ifdef _CS_HOSTNAME
5407 {"CS_HOSTNAME", _CS_HOSTNAME},
5408#endif
5409#ifdef _CS_HW_PROVIDER
5410 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5411#endif
5412#ifdef _CS_HW_SERIAL
5413 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5414#endif
5415#ifdef _CS_INITTAB_NAME
5416 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5417#endif
Fred Drakec9680921999-12-13 16:37:25 +00005418#ifdef _CS_LFS64_CFLAGS
5419 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5420#endif
5421#ifdef _CS_LFS64_LDFLAGS
5422 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5423#endif
5424#ifdef _CS_LFS64_LIBS
5425 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5426#endif
5427#ifdef _CS_LFS64_LINTFLAGS
5428 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5429#endif
5430#ifdef _CS_LFS_CFLAGS
5431 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5432#endif
5433#ifdef _CS_LFS_LDFLAGS
5434 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5435#endif
5436#ifdef _CS_LFS_LIBS
5437 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5438#endif
5439#ifdef _CS_LFS_LINTFLAGS
5440 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5441#endif
Fred Draked86ed291999-12-15 15:34:33 +00005442#ifdef _CS_MACHINE
5443 {"CS_MACHINE", _CS_MACHINE},
5444#endif
Fred Drakec9680921999-12-13 16:37:25 +00005445#ifdef _CS_PATH
5446 {"CS_PATH", _CS_PATH},
5447#endif
Fred Draked86ed291999-12-15 15:34:33 +00005448#ifdef _CS_RELEASE
5449 {"CS_RELEASE", _CS_RELEASE},
5450#endif
5451#ifdef _CS_SRPC_DOMAIN
5452 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5453#endif
5454#ifdef _CS_SYSNAME
5455 {"CS_SYSNAME", _CS_SYSNAME},
5456#endif
5457#ifdef _CS_VERSION
5458 {"CS_VERSION", _CS_VERSION},
5459#endif
Fred Drakec9680921999-12-13 16:37:25 +00005460#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5461 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5462#endif
5463#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5464 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5465#endif
5466#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5467 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5468#endif
5469#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5470 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5471#endif
5472#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5473 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5474#endif
5475#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5476 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5477#endif
5478#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5479 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5480#endif
5481#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5482 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5483#endif
5484#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5485 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5486#endif
5487#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5488 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5489#endif
5490#ifdef _CS_XBS5_LP64_OFF64_LIBS
5491 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5492#endif
5493#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5494 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5495#endif
5496#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5497 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5498#endif
5499#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5500 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5501#endif
5502#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5503 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5504#endif
5505#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5506 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5507#endif
Fred Draked86ed291999-12-15 15:34:33 +00005508#ifdef _MIPS_CS_AVAIL_PROCESSORS
5509 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5510#endif
5511#ifdef _MIPS_CS_BASE
5512 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5513#endif
5514#ifdef _MIPS_CS_HOSTID
5515 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5516#endif
5517#ifdef _MIPS_CS_HW_NAME
5518 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5519#endif
5520#ifdef _MIPS_CS_NUM_PROCESSORS
5521 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5522#endif
5523#ifdef _MIPS_CS_OSREL_MAJ
5524 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5525#endif
5526#ifdef _MIPS_CS_OSREL_MIN
5527 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5528#endif
5529#ifdef _MIPS_CS_OSREL_PATCH
5530 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5531#endif
5532#ifdef _MIPS_CS_OS_NAME
5533 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5534#endif
5535#ifdef _MIPS_CS_OS_PROVIDER
5536 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5537#endif
5538#ifdef _MIPS_CS_PROCESSORS
5539 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5540#endif
5541#ifdef _MIPS_CS_SERIAL
5542 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5543#endif
5544#ifdef _MIPS_CS_VENDOR
5545 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5546#endif
Fred Drakec9680921999-12-13 16:37:25 +00005547};
5548
5549static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005550conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005551{
5552 return conv_confname(arg, valuep, posix_constants_confstr,
5553 sizeof(posix_constants_confstr)
5554 / sizeof(struct constdef));
5555}
5556
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005558"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005559Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005560
5561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005562posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005563{
5564 PyObject *result = NULL;
5565 int name;
5566 char buffer[64];
5567
5568 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5569 int len = confstr(name, buffer, sizeof(buffer));
5570
Fred Drakec9680921999-12-13 16:37:25 +00005571 errno = 0;
5572 if (len == 0) {
5573 if (errno != 0)
5574 posix_error();
5575 else
5576 result = PyString_FromString("");
5577 }
5578 else {
5579 if (len >= sizeof(buffer)) {
5580 result = PyString_FromStringAndSize(NULL, len);
5581 if (result != NULL)
5582 confstr(name, PyString_AS_STRING(result), len+1);
5583 }
5584 else
5585 result = PyString_FromString(buffer);
5586 }
5587 }
5588 return result;
5589}
5590#endif
5591
5592
5593#ifdef HAVE_SYSCONF
5594static struct constdef posix_constants_sysconf[] = {
5595#ifdef _SC_2_CHAR_TERM
5596 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5597#endif
5598#ifdef _SC_2_C_BIND
5599 {"SC_2_C_BIND", _SC_2_C_BIND},
5600#endif
5601#ifdef _SC_2_C_DEV
5602 {"SC_2_C_DEV", _SC_2_C_DEV},
5603#endif
5604#ifdef _SC_2_C_VERSION
5605 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5606#endif
5607#ifdef _SC_2_FORT_DEV
5608 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5609#endif
5610#ifdef _SC_2_FORT_RUN
5611 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5612#endif
5613#ifdef _SC_2_LOCALEDEF
5614 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5615#endif
5616#ifdef _SC_2_SW_DEV
5617 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5618#endif
5619#ifdef _SC_2_UPE
5620 {"SC_2_UPE", _SC_2_UPE},
5621#endif
5622#ifdef _SC_2_VERSION
5623 {"SC_2_VERSION", _SC_2_VERSION},
5624#endif
Fred Draked86ed291999-12-15 15:34:33 +00005625#ifdef _SC_ABI_ASYNCHRONOUS_IO
5626 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5627#endif
5628#ifdef _SC_ACL
5629 {"SC_ACL", _SC_ACL},
5630#endif
Fred Drakec9680921999-12-13 16:37:25 +00005631#ifdef _SC_AIO_LISTIO_MAX
5632 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5633#endif
Fred Drakec9680921999-12-13 16:37:25 +00005634#ifdef _SC_AIO_MAX
5635 {"SC_AIO_MAX", _SC_AIO_MAX},
5636#endif
5637#ifdef _SC_AIO_PRIO_DELTA_MAX
5638 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5639#endif
5640#ifdef _SC_ARG_MAX
5641 {"SC_ARG_MAX", _SC_ARG_MAX},
5642#endif
5643#ifdef _SC_ASYNCHRONOUS_IO
5644 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5645#endif
5646#ifdef _SC_ATEXIT_MAX
5647 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5648#endif
Fred Draked86ed291999-12-15 15:34:33 +00005649#ifdef _SC_AUDIT
5650 {"SC_AUDIT", _SC_AUDIT},
5651#endif
Fred Drakec9680921999-12-13 16:37:25 +00005652#ifdef _SC_AVPHYS_PAGES
5653 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5654#endif
5655#ifdef _SC_BC_BASE_MAX
5656 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5657#endif
5658#ifdef _SC_BC_DIM_MAX
5659 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5660#endif
5661#ifdef _SC_BC_SCALE_MAX
5662 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5663#endif
5664#ifdef _SC_BC_STRING_MAX
5665 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5666#endif
Fred Draked86ed291999-12-15 15:34:33 +00005667#ifdef _SC_CAP
5668 {"SC_CAP", _SC_CAP},
5669#endif
Fred Drakec9680921999-12-13 16:37:25 +00005670#ifdef _SC_CHARCLASS_NAME_MAX
5671 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5672#endif
5673#ifdef _SC_CHAR_BIT
5674 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5675#endif
5676#ifdef _SC_CHAR_MAX
5677 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5678#endif
5679#ifdef _SC_CHAR_MIN
5680 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5681#endif
5682#ifdef _SC_CHILD_MAX
5683 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5684#endif
5685#ifdef _SC_CLK_TCK
5686 {"SC_CLK_TCK", _SC_CLK_TCK},
5687#endif
5688#ifdef _SC_COHER_BLKSZ
5689 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5690#endif
5691#ifdef _SC_COLL_WEIGHTS_MAX
5692 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5693#endif
5694#ifdef _SC_DCACHE_ASSOC
5695 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5696#endif
5697#ifdef _SC_DCACHE_BLKSZ
5698 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5699#endif
5700#ifdef _SC_DCACHE_LINESZ
5701 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5702#endif
5703#ifdef _SC_DCACHE_SZ
5704 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5705#endif
5706#ifdef _SC_DCACHE_TBLKSZ
5707 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5708#endif
5709#ifdef _SC_DELAYTIMER_MAX
5710 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5711#endif
5712#ifdef _SC_EQUIV_CLASS_MAX
5713 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5714#endif
5715#ifdef _SC_EXPR_NEST_MAX
5716 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5717#endif
5718#ifdef _SC_FSYNC
5719 {"SC_FSYNC", _SC_FSYNC},
5720#endif
5721#ifdef _SC_GETGR_R_SIZE_MAX
5722 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5723#endif
5724#ifdef _SC_GETPW_R_SIZE_MAX
5725 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5726#endif
5727#ifdef _SC_ICACHE_ASSOC
5728 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5729#endif
5730#ifdef _SC_ICACHE_BLKSZ
5731 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5732#endif
5733#ifdef _SC_ICACHE_LINESZ
5734 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5735#endif
5736#ifdef _SC_ICACHE_SZ
5737 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5738#endif
Fred Draked86ed291999-12-15 15:34:33 +00005739#ifdef _SC_INF
5740 {"SC_INF", _SC_INF},
5741#endif
Fred Drakec9680921999-12-13 16:37:25 +00005742#ifdef _SC_INT_MAX
5743 {"SC_INT_MAX", _SC_INT_MAX},
5744#endif
5745#ifdef _SC_INT_MIN
5746 {"SC_INT_MIN", _SC_INT_MIN},
5747#endif
5748#ifdef _SC_IOV_MAX
5749 {"SC_IOV_MAX", _SC_IOV_MAX},
5750#endif
Fred Draked86ed291999-12-15 15:34:33 +00005751#ifdef _SC_IP_SECOPTS
5752 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5753#endif
Fred Drakec9680921999-12-13 16:37:25 +00005754#ifdef _SC_JOB_CONTROL
5755 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5756#endif
Fred Draked86ed291999-12-15 15:34:33 +00005757#ifdef _SC_KERN_POINTERS
5758 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5759#endif
5760#ifdef _SC_KERN_SIM
5761 {"SC_KERN_SIM", _SC_KERN_SIM},
5762#endif
Fred Drakec9680921999-12-13 16:37:25 +00005763#ifdef _SC_LINE_MAX
5764 {"SC_LINE_MAX", _SC_LINE_MAX},
5765#endif
5766#ifdef _SC_LOGIN_NAME_MAX
5767 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5768#endif
5769#ifdef _SC_LOGNAME_MAX
5770 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5771#endif
5772#ifdef _SC_LONG_BIT
5773 {"SC_LONG_BIT", _SC_LONG_BIT},
5774#endif
Fred Draked86ed291999-12-15 15:34:33 +00005775#ifdef _SC_MAC
5776 {"SC_MAC", _SC_MAC},
5777#endif
Fred Drakec9680921999-12-13 16:37:25 +00005778#ifdef _SC_MAPPED_FILES
5779 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5780#endif
5781#ifdef _SC_MAXPID
5782 {"SC_MAXPID", _SC_MAXPID},
5783#endif
5784#ifdef _SC_MB_LEN_MAX
5785 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5786#endif
5787#ifdef _SC_MEMLOCK
5788 {"SC_MEMLOCK", _SC_MEMLOCK},
5789#endif
5790#ifdef _SC_MEMLOCK_RANGE
5791 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5792#endif
5793#ifdef _SC_MEMORY_PROTECTION
5794 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5795#endif
5796#ifdef _SC_MESSAGE_PASSING
5797 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5798#endif
Fred Draked86ed291999-12-15 15:34:33 +00005799#ifdef _SC_MMAP_FIXED_ALIGNMENT
5800 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5801#endif
Fred Drakec9680921999-12-13 16:37:25 +00005802#ifdef _SC_MQ_OPEN_MAX
5803 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5804#endif
5805#ifdef _SC_MQ_PRIO_MAX
5806 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5807#endif
Fred Draked86ed291999-12-15 15:34:33 +00005808#ifdef _SC_NACLS_MAX
5809 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5810#endif
Fred Drakec9680921999-12-13 16:37:25 +00005811#ifdef _SC_NGROUPS_MAX
5812 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5813#endif
5814#ifdef _SC_NL_ARGMAX
5815 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5816#endif
5817#ifdef _SC_NL_LANGMAX
5818 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5819#endif
5820#ifdef _SC_NL_MSGMAX
5821 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5822#endif
5823#ifdef _SC_NL_NMAX
5824 {"SC_NL_NMAX", _SC_NL_NMAX},
5825#endif
5826#ifdef _SC_NL_SETMAX
5827 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5828#endif
5829#ifdef _SC_NL_TEXTMAX
5830 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5831#endif
5832#ifdef _SC_NPROCESSORS_CONF
5833 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5834#endif
5835#ifdef _SC_NPROCESSORS_ONLN
5836 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5837#endif
Fred Draked86ed291999-12-15 15:34:33 +00005838#ifdef _SC_NPROC_CONF
5839 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5840#endif
5841#ifdef _SC_NPROC_ONLN
5842 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5843#endif
Fred Drakec9680921999-12-13 16:37:25 +00005844#ifdef _SC_NZERO
5845 {"SC_NZERO", _SC_NZERO},
5846#endif
5847#ifdef _SC_OPEN_MAX
5848 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5849#endif
5850#ifdef _SC_PAGESIZE
5851 {"SC_PAGESIZE", _SC_PAGESIZE},
5852#endif
5853#ifdef _SC_PAGE_SIZE
5854 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5855#endif
5856#ifdef _SC_PASS_MAX
5857 {"SC_PASS_MAX", _SC_PASS_MAX},
5858#endif
5859#ifdef _SC_PHYS_PAGES
5860 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5861#endif
5862#ifdef _SC_PII
5863 {"SC_PII", _SC_PII},
5864#endif
5865#ifdef _SC_PII_INTERNET
5866 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5867#endif
5868#ifdef _SC_PII_INTERNET_DGRAM
5869 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5870#endif
5871#ifdef _SC_PII_INTERNET_STREAM
5872 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5873#endif
5874#ifdef _SC_PII_OSI
5875 {"SC_PII_OSI", _SC_PII_OSI},
5876#endif
5877#ifdef _SC_PII_OSI_CLTS
5878 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5879#endif
5880#ifdef _SC_PII_OSI_COTS
5881 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5882#endif
5883#ifdef _SC_PII_OSI_M
5884 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5885#endif
5886#ifdef _SC_PII_SOCKET
5887 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5888#endif
5889#ifdef _SC_PII_XTI
5890 {"SC_PII_XTI", _SC_PII_XTI},
5891#endif
5892#ifdef _SC_POLL
5893 {"SC_POLL", _SC_POLL},
5894#endif
5895#ifdef _SC_PRIORITIZED_IO
5896 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5897#endif
5898#ifdef _SC_PRIORITY_SCHEDULING
5899 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5900#endif
5901#ifdef _SC_REALTIME_SIGNALS
5902 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5903#endif
5904#ifdef _SC_RE_DUP_MAX
5905 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5906#endif
5907#ifdef _SC_RTSIG_MAX
5908 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5909#endif
5910#ifdef _SC_SAVED_IDS
5911 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5912#endif
5913#ifdef _SC_SCHAR_MAX
5914 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5915#endif
5916#ifdef _SC_SCHAR_MIN
5917 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5918#endif
5919#ifdef _SC_SELECT
5920 {"SC_SELECT", _SC_SELECT},
5921#endif
5922#ifdef _SC_SEMAPHORES
5923 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5924#endif
5925#ifdef _SC_SEM_NSEMS_MAX
5926 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5927#endif
5928#ifdef _SC_SEM_VALUE_MAX
5929 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5930#endif
5931#ifdef _SC_SHARED_MEMORY_OBJECTS
5932 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5933#endif
5934#ifdef _SC_SHRT_MAX
5935 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5936#endif
5937#ifdef _SC_SHRT_MIN
5938 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5939#endif
5940#ifdef _SC_SIGQUEUE_MAX
5941 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5942#endif
5943#ifdef _SC_SIGRT_MAX
5944 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5945#endif
5946#ifdef _SC_SIGRT_MIN
5947 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5948#endif
Fred Draked86ed291999-12-15 15:34:33 +00005949#ifdef _SC_SOFTPOWER
5950 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5951#endif
Fred Drakec9680921999-12-13 16:37:25 +00005952#ifdef _SC_SPLIT_CACHE
5953 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5954#endif
5955#ifdef _SC_SSIZE_MAX
5956 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5957#endif
5958#ifdef _SC_STACK_PROT
5959 {"SC_STACK_PROT", _SC_STACK_PROT},
5960#endif
5961#ifdef _SC_STREAM_MAX
5962 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5963#endif
5964#ifdef _SC_SYNCHRONIZED_IO
5965 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5966#endif
5967#ifdef _SC_THREADS
5968 {"SC_THREADS", _SC_THREADS},
5969#endif
5970#ifdef _SC_THREAD_ATTR_STACKADDR
5971 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5972#endif
5973#ifdef _SC_THREAD_ATTR_STACKSIZE
5974 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5975#endif
5976#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5977 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5978#endif
5979#ifdef _SC_THREAD_KEYS_MAX
5980 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5981#endif
5982#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5983 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5984#endif
5985#ifdef _SC_THREAD_PRIO_INHERIT
5986 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5987#endif
5988#ifdef _SC_THREAD_PRIO_PROTECT
5989 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5990#endif
5991#ifdef _SC_THREAD_PROCESS_SHARED
5992 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5993#endif
5994#ifdef _SC_THREAD_SAFE_FUNCTIONS
5995 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5996#endif
5997#ifdef _SC_THREAD_STACK_MIN
5998 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5999#endif
6000#ifdef _SC_THREAD_THREADS_MAX
6001 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6002#endif
6003#ifdef _SC_TIMERS
6004 {"SC_TIMERS", _SC_TIMERS},
6005#endif
6006#ifdef _SC_TIMER_MAX
6007 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6008#endif
6009#ifdef _SC_TTY_NAME_MAX
6010 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6011#endif
6012#ifdef _SC_TZNAME_MAX
6013 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6014#endif
6015#ifdef _SC_T_IOV_MAX
6016 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6017#endif
6018#ifdef _SC_UCHAR_MAX
6019 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6020#endif
6021#ifdef _SC_UINT_MAX
6022 {"SC_UINT_MAX", _SC_UINT_MAX},
6023#endif
6024#ifdef _SC_UIO_MAXIOV
6025 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6026#endif
6027#ifdef _SC_ULONG_MAX
6028 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6029#endif
6030#ifdef _SC_USHRT_MAX
6031 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6032#endif
6033#ifdef _SC_VERSION
6034 {"SC_VERSION", _SC_VERSION},
6035#endif
6036#ifdef _SC_WORD_BIT
6037 {"SC_WORD_BIT", _SC_WORD_BIT},
6038#endif
6039#ifdef _SC_XBS5_ILP32_OFF32
6040 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6041#endif
6042#ifdef _SC_XBS5_ILP32_OFFBIG
6043 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6044#endif
6045#ifdef _SC_XBS5_LP64_OFF64
6046 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6047#endif
6048#ifdef _SC_XBS5_LPBIG_OFFBIG
6049 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6050#endif
6051#ifdef _SC_XOPEN_CRYPT
6052 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6053#endif
6054#ifdef _SC_XOPEN_ENH_I18N
6055 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6056#endif
6057#ifdef _SC_XOPEN_LEGACY
6058 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6059#endif
6060#ifdef _SC_XOPEN_REALTIME
6061 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6062#endif
6063#ifdef _SC_XOPEN_REALTIME_THREADS
6064 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6065#endif
6066#ifdef _SC_XOPEN_SHM
6067 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6068#endif
6069#ifdef _SC_XOPEN_UNIX
6070 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6071#endif
6072#ifdef _SC_XOPEN_VERSION
6073 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6074#endif
6075#ifdef _SC_XOPEN_XCU_VERSION
6076 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6077#endif
6078#ifdef _SC_XOPEN_XPG2
6079 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6080#endif
6081#ifdef _SC_XOPEN_XPG3
6082 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6083#endif
6084#ifdef _SC_XOPEN_XPG4
6085 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6086#endif
6087};
6088
6089static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006090conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006091{
6092 return conv_confname(arg, valuep, posix_constants_sysconf,
6093 sizeof(posix_constants_sysconf)
6094 / sizeof(struct constdef));
6095}
6096
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006098"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006100
6101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006102posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006103{
6104 PyObject *result = NULL;
6105 int name;
6106
6107 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6108 int value;
6109
6110 errno = 0;
6111 value = sysconf(name);
6112 if (value == -1 && errno != 0)
6113 posix_error();
6114 else
6115 result = PyInt_FromLong(value);
6116 }
6117 return result;
6118}
6119#endif
6120
6121
Fred Drakebec628d1999-12-15 18:31:10 +00006122/* This code is used to ensure that the tables of configuration value names
6123 * are in sorted order as required by conv_confname(), and also to build the
6124 * the exported dictionaries that are used to publish information about the
6125 * names available on the host platform.
6126 *
6127 * Sorting the table at runtime ensures that the table is properly ordered
6128 * when used, even for platforms we're not able to test on. It also makes
6129 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006130 */
Fred Drakebec628d1999-12-15 18:31:10 +00006131
6132static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006133cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006134{
6135 const struct constdef *c1 =
6136 (const struct constdef *) v1;
6137 const struct constdef *c2 =
6138 (const struct constdef *) v2;
6139
6140 return strcmp(c1->name, c2->name);
6141}
6142
6143static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006144setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006145 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006146{
Fred Drakebec628d1999-12-15 18:31:10 +00006147 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006148 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006149
6150 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6151 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006152 if (d == NULL)
6153 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006154
Barry Warsaw3155db32000-04-13 15:20:40 +00006155 for (i=0; i < tablesize; ++i) {
6156 PyObject *o = PyInt_FromLong(table[i].value);
6157 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6158 Py_XDECREF(o);
6159 Py_DECREF(d);
6160 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006161 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006162 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006163 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006164 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006165}
6166
Fred Drakebec628d1999-12-15 18:31:10 +00006167/* Return -1 on failure, 0 on success. */
6168static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006169setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006170{
6171#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006172 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006173 sizeof(posix_constants_pathconf)
6174 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006175 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006176 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006177#endif
6178#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006179 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006180 sizeof(posix_constants_confstr)
6181 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006182 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006183 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006184#endif
6185#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006186 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006187 sizeof(posix_constants_sysconf)
6188 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006189 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006190 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006191#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006192 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006193}
Fred Draked86ed291999-12-15 15:34:33 +00006194
6195
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006196PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006197"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006198Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006199in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006200
6201static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006202posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006203{
6204 if (!PyArg_ParseTuple(args, ":abort"))
6205 return NULL;
6206 abort();
6207 /*NOTREACHED*/
6208 Py_FatalError("abort() called from Python code didn't abort!");
6209 return NULL;
6210}
Fred Drakebec628d1999-12-15 18:31:10 +00006211
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006212#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006213PyDoc_STRVAR(win32_startfile__doc__,
6214"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006215\n\
6216This acts like double-clicking the file in Explorer, or giving the file\n\
6217name as an argument to the DOS \"start\" command: the file is opened\n\
6218with whatever application (if any) its extension is associated.\n\
6219\n\
6220startfile returns as soon as the associated application is launched.\n\
6221There is no option to wait for the application to close, and no way\n\
6222to retrieve the application's exit status.\n\
6223\n\
6224The filepath is relative to the current directory. If you want to use\n\
6225an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006226the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006227
6228static PyObject *
6229win32_startfile(PyObject *self, PyObject *args)
6230{
6231 char *filepath;
6232 HINSTANCE rc;
6233 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6234 return NULL;
6235 Py_BEGIN_ALLOW_THREADS
6236 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6237 Py_END_ALLOW_THREADS
6238 if (rc <= (HINSTANCE)32)
6239 return win32_error("startfile", filepath);
6240 Py_INCREF(Py_None);
6241 return Py_None;
6242}
6243#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006244
6245static PyMethodDef posix_methods[] = {
6246 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6247#ifdef HAVE_TTYNAME
6248 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6249#endif
6250 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6251 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006252#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006253 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006254#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006255#ifdef HAVE_LCHOWN
6256 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6257#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006258#ifdef HAVE_CHROOT
6259 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6260#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006261#ifdef HAVE_CTERMID
6262 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6263#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006264#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006265 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006266#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006267#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006268 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006269#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006270 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6271 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6272 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006273#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006274 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006275#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006276#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006277 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006278#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006279 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6280 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6281 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006282#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006283 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006284#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006285#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006286 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006287#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006288 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006289#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006290 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006291#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006292 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6293 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6294 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006295#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006296 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006297#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006298 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006299#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006300 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6301 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006302#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006303#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006304 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6305 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006306#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006307#ifdef HAVE_FORK1
6308 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6309#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006310#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006311 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006312#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006313#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006314 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006315#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006316#ifdef HAVE_FORKPTY
6317 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6318#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006319#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006320 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006321#endif /* HAVE_GETEGID */
6322#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006323 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006324#endif /* HAVE_GETEUID */
6325#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006326 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006327#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006328#ifdef HAVE_GETGROUPS
6329 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6330#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006331 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006332#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006333 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006334#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006335#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006336 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006337#endif /* HAVE_GETPPID */
6338#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006339 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006340#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006341#ifdef HAVE_GETLOGIN
6342 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6343#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006344#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006345 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006346#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006347#ifdef HAVE_KILLPG
6348 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6349#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006350#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006351 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006352#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006353#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006354 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006355#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006356 {"popen2", win32_popen2, METH_VARARGS},
6357 {"popen3", win32_popen3, METH_VARARGS},
6358 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006359 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006360#else
6361#if defined(PYOS_OS2) && defined(PYCC_GCC)
6362 {"popen2", os2emx_popen2, METH_VARARGS},
6363 {"popen3", os2emx_popen3, METH_VARARGS},
6364 {"popen4", os2emx_popen4, METH_VARARGS},
6365#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006366#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006367#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006368#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006369 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006370#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006371#ifdef HAVE_SETEUID
6372 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6373#endif /* HAVE_SETEUID */
6374#ifdef HAVE_SETEGID
6375 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6376#endif /* HAVE_SETEGID */
6377#ifdef HAVE_SETREUID
6378 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6379#endif /* HAVE_SETREUID */
6380#ifdef HAVE_SETREGID
6381 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6382#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006383#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006384 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006385#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006386#ifdef HAVE_SETGROUPS
6387 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6388#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006389#ifdef HAVE_GETPGID
6390 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6391#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006392#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006393 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006394#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006395#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006396 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006397#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006398#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006399 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006400#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006401#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006402 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006403#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006404#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006405 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006406#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006407#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006408 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006409#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006410#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006411 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006412#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006413 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6414 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6415 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6416 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6417 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6418 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6419 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6420 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6421 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006422 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006423#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006424 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006425#endif
6426#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006427 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006428#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006429#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006430 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6431#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006432#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006433 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006434#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006435#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006436 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006437#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006438#ifdef HAVE_UNSETENV
6439 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6440#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006441#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006442 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006443#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006444#ifdef HAVE_FCHDIR
6445 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6446#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006447#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006448 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006449#endif
6450#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006451 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006452#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006453#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006454#ifdef WCOREDUMP
6455 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6456#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006457#ifdef WIFCONTINUED
6458 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6459#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006460#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006461 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006462#endif /* WIFSTOPPED */
6463#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006464 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006465#endif /* WIFSIGNALED */
6466#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006467 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006468#endif /* WIFEXITED */
6469#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006470 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006471#endif /* WEXITSTATUS */
6472#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006473 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006474#endif /* WTERMSIG */
6475#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006476 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006477#endif /* WSTOPSIG */
6478#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006479#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006480 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006481#endif
6482#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006483 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006484#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006485#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006486 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6487#endif
6488#ifdef HAVE_TEMPNAM
6489 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6490#endif
6491#ifdef HAVE_TMPNAM
6492 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6493#endif
Fred Drakec9680921999-12-13 16:37:25 +00006494#ifdef HAVE_CONFSTR
6495 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6496#endif
6497#ifdef HAVE_SYSCONF
6498 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6499#endif
6500#ifdef HAVE_FPATHCONF
6501 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6502#endif
6503#ifdef HAVE_PATHCONF
6504 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6505#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006506 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006507#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006508 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6509#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006510 {NULL, NULL} /* Sentinel */
6511};
6512
6513
Barry Warsaw4a342091996-12-19 23:50:02 +00006514static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006515ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006516{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006517 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006518}
6519
Guido van Rossumd48f2521997-12-05 22:19:34 +00006520#if defined(PYOS_OS2)
6521/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006522static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006523{
6524 APIRET rc;
6525 ULONG values[QSV_MAX+1];
6526 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006527 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006528
6529 Py_BEGIN_ALLOW_THREADS
6530 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6531 Py_END_ALLOW_THREADS
6532
6533 if (rc != NO_ERROR) {
6534 os2_error(rc);
6535 return -1;
6536 }
6537
Fred Drake4d1e64b2002-04-15 19:40:07 +00006538 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6539 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6540 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6541 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6542 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6543 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6544 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006545
6546 switch (values[QSV_VERSION_MINOR]) {
6547 case 0: ver = "2.00"; break;
6548 case 10: ver = "2.10"; break;
6549 case 11: ver = "2.11"; break;
6550 case 30: ver = "3.00"; break;
6551 case 40: ver = "4.00"; break;
6552 case 50: ver = "5.00"; break;
6553 default:
Tim Peters885d4572001-11-28 20:27:42 +00006554 PyOS_snprintf(tmp, sizeof(tmp),
6555 "%d-%d", values[QSV_VERSION_MAJOR],
6556 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006557 ver = &tmp[0];
6558 }
6559
6560 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006561 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006562 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006563
6564 /* Add Indicator of Which Drive was Used to Boot the System */
6565 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6566 tmp[1] = ':';
6567 tmp[2] = '\0';
6568
Fred Drake4d1e64b2002-04-15 19:40:07 +00006569 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006570}
6571#endif
6572
Barry Warsaw4a342091996-12-19 23:50:02 +00006573static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006574all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006575{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006576#ifdef F_OK
6577 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006578#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006579#ifdef R_OK
6580 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006581#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006582#ifdef W_OK
6583 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006584#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006585#ifdef X_OK
6586 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006587#endif
Fred Drakec9680921999-12-13 16:37:25 +00006588#ifdef NGROUPS_MAX
6589 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6590#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006591#ifdef TMP_MAX
6592 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6593#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006594#ifdef WCONTINUED
6595 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6596#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006597#ifdef WNOHANG
6598 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006599#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006600#ifdef WUNTRACED
6601 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6602#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006603#ifdef O_RDONLY
6604 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6605#endif
6606#ifdef O_WRONLY
6607 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6608#endif
6609#ifdef O_RDWR
6610 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6611#endif
6612#ifdef O_NDELAY
6613 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6614#endif
6615#ifdef O_NONBLOCK
6616 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6617#endif
6618#ifdef O_APPEND
6619 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6620#endif
6621#ifdef O_DSYNC
6622 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6623#endif
6624#ifdef O_RSYNC
6625 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6626#endif
6627#ifdef O_SYNC
6628 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6629#endif
6630#ifdef O_NOCTTY
6631 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6632#endif
6633#ifdef O_CREAT
6634 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6635#endif
6636#ifdef O_EXCL
6637 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6638#endif
6639#ifdef O_TRUNC
6640 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6641#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006642#ifdef O_BINARY
6643 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6644#endif
6645#ifdef O_TEXT
6646 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6647#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006648#ifdef O_LARGEFILE
6649 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6650#endif
6651
Tim Peters5aa91602002-01-30 05:46:57 +00006652/* MS Windows */
6653#ifdef O_NOINHERIT
6654 /* Don't inherit in child processes. */
6655 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6656#endif
6657#ifdef _O_SHORT_LIVED
6658 /* Optimize for short life (keep in memory). */
6659 /* MS forgot to define this one with a non-underscore form too. */
6660 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6661#endif
6662#ifdef O_TEMPORARY
6663 /* Automatically delete when last handle is closed. */
6664 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6665#endif
6666#ifdef O_RANDOM
6667 /* Optimize for random access. */
6668 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6669#endif
6670#ifdef O_SEQUENTIAL
6671 /* Optimize for sequential access. */
6672 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6673#endif
6674
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006675/* GNU extensions. */
6676#ifdef O_DIRECT
6677 /* Direct disk access. */
6678 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6679#endif
6680#ifdef O_DIRECTORY
6681 /* Must be a directory. */
6682 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6683#endif
6684#ifdef O_NOFOLLOW
6685 /* Do not follow links. */
6686 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6687#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006688
Guido van Rossum246bc171999-02-01 23:54:31 +00006689#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006690#if defined(PYOS_OS2) && defined(PYCC_GCC)
6691 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6692 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6693 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6694 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6695 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6696 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6697 if (ins(d, "P_PM", (long)P_PM)) return -1;
6698 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6699 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6700 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6701 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6702 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6703 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6704 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6705 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6706 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6707 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6708 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6709 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6710 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6711#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006712 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6713 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6714 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6715 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6716 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006717#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006718#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006719
Guido van Rossumd48f2521997-12-05 22:19:34 +00006720#if defined(PYOS_OS2)
6721 if (insertvalues(d)) return -1;
6722#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006723 return 0;
6724}
6725
6726
Tim Peters5aa91602002-01-30 05:46:57 +00006727#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006728#define INITFUNC initnt
6729#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006730
6731#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006732#define INITFUNC initos2
6733#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006734
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006735#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006736#define INITFUNC initposix
6737#define MODNAME "posix"
6738#endif
6739
Guido van Rossum3886bb61998-12-04 18:50:17 +00006740DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006741INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006742{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006743 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006744
Fred Drake4d1e64b2002-04-15 19:40:07 +00006745 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006746 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006747 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006748
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006749 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006750 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006751 Py_XINCREF(v);
6752 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006753 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006754 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006755
Fred Drake4d1e64b2002-04-15 19:40:07 +00006756 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006757 return;
6758
Fred Drake4d1e64b2002-04-15 19:40:07 +00006759 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006760 return;
6761
Fred Drake4d1e64b2002-04-15 19:40:07 +00006762 Py_INCREF(PyExc_OSError);
6763 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006764
Guido van Rossumb3d39562000-01-31 18:41:26 +00006765#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006766 if (posix_putenv_garbage == NULL)
6767 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006768#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006769
Guido van Rossum14648392001-12-08 18:02:58 +00006770 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006771 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006772 Py_INCREF((PyObject*) &StatResultType);
6773 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006774
Guido van Rossum14648392001-12-08 18:02:58 +00006775 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006776 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006777 Py_INCREF((PyObject*) &StatVFSResultType);
6778 PyModule_AddObject(m, "statvfs_result",
6779 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006780}