blob: b26c89eccfc642f91776ddcfa1bc7fd1ddd6356d [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004/* This file is also used for Windows NT and MS-Win. In that case the module
Guido van Rossumad0ee831995-03-01 10:34:45 +00005 actually calls itself 'nt', not 'posix', and a few functions are
6 either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +00007 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000013static char posix__doc__ [] =
14"This module provides access to operating system functionality that is\n\
15standardized by the C Standard and the POSIX standard (a thinly\n\
16disguised Unix interface). Refer to the library manual and\n\
17corresponding Unix manual entries for more information on calls.";
18
Barry Warsaw53699e91996-12-10 23:23:01 +000019#include "Python.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000020
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000021#if defined(PYOS_OS2)
22#define INCL_DOS
23#define INCL_DOSERRORS
24#define INCL_DOSPROCESS
25#define INCL_NOPMAPI
26#include <os2.h>
27#endif
28
Guido van Rossumb6775db1994-08-01 11:34:53 +000029#include <sys/types.h>
30#include <sys/stat.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +000031#ifdef HAVE_SYS_WAIT_H
32#include <sys/wait.h> /* For WNOHANG */
33#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000034
Guido van Rossuma376cc51996-12-05 23:43:35 +000035#ifdef HAVE_SIGNAL_H
36#include <signal.h>
37#endif
38
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#ifdef HAVE_FCNTL_H
40#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000041#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000042
Skip Montanaro8216c182001-02-27 17:04:34 +000043/* pick up declaration of confstr on some systems? */
44#ifdef HAVE_UNISTD_H
45#include <unistd.h>
46#endif /* HAVE_UNISTD_H */
47
Guido van Rossuma4916fa1996-05-23 22:58:55 +000048/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000049/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000050#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#include <process.h>
52#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000053#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000054#define HAVE_GETCWD 1
55#define HAVE_OPENDIR 1
56#define HAVE_SYSTEM 1
57#if defined(__OS2__)
58#define HAVE_EXECV 1
59#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000060#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000061#include <process.h>
62#else
63#ifdef __BORLANDC__ /* Borland compiler */
64#define HAVE_EXECV 1
65#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000066#define HAVE_OPENDIR 1
67#define HAVE_PIPE 1
68#define HAVE_POPEN 1
69#define HAVE_SYSTEM 1
70#define HAVE_WAIT 1
71#else
72#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000073#define HAVE_GETCWD 1
74#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000075#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000076#define HAVE_EXECV 1
77#define HAVE_PIPE 1
78#define HAVE_POPEN 1
79#define HAVE_SYSTEM 1
80#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000081#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#else /* all other compilers */
83/* Unix functions that the configure script doesn't check for */
84#define HAVE_EXECV 1
85#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000086#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
87#define HAVE_FORK1 1
88#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000089#define HAVE_GETCWD 1
90#define HAVE_GETEGID 1
91#define HAVE_GETEUID 1
92#define HAVE_GETGID 1
93#define HAVE_GETPPID 1
94#define HAVE_GETUID 1
95#define HAVE_KILL 1
96#define HAVE_OPENDIR 1
97#define HAVE_PIPE 1
98#define HAVE_POPEN 1
99#define HAVE_SYSTEM 1
100#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000101#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000102#endif /* _MSC_VER */
103#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000105#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000106
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000107#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000108
Guido van Rossumb6775db1994-08-01 11:34:53 +0000109#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000110#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000111#endif
112
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000113#if defined(sun) && !defined(__SVR4)
114/* SunOS 4.1.4 doesn't have prototypes for these: */
115extern int rename(const char *, const char *);
116extern int pclose(FILE *);
117extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000118extern int fsync(int);
119extern int lstat(const char *, struct stat *);
120extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000121#endif
122
Guido van Rossum36bc6801995-06-14 22:54:23 +0000123#ifdef NeXT
124/* NeXT's <unistd.h> and <utime.h> aren't worth much */
125#undef HAVE_UNISTD_H
126#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000127#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000128/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000129#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +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
193#ifndef MAXPATHLEN
194#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000195#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000197#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#define NAMLEN(dirent) strlen((dirent)->d_name)
200#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000201#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000202#include <direct.h>
203#define NAMLEN(dirent) strlen((dirent)->d_name)
204#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000207#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#endif
211#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000213#endif
214#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000216#endif
217#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000219#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220#include <direct.h>
221#include <io.h>
222#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000223#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000225#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000227#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#else /* 16-bit Windows */
229#include <dos.h>
230#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000231#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233
Guido van Rossumd48f2521997-12-05 22:19:34 +0000234#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000236#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000238#ifdef UNION_WAIT
239/* Emulate some macros on systems that have a union instead of macros */
240
241#ifndef WIFEXITED
242#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
243#endif
244
245#ifndef WEXITSTATUS
246#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
247#endif
248
249#ifndef WTERMSIG
250#define WTERMSIG(u_wait) ((u_wait).w_termsig)
251#endif
252
253#endif /* UNION_WAIT */
254
Greg Wardb48bc172000-03-01 21:51:56 +0000255/* Don't use the "_r" form if we don't need it (also, won't have a
256 prototype for it, at least on Solaris -- maybe others as well?). */
257#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
258#define USE_CTERMID_R
259#endif
260
261#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
262#define USE_TMPNAM_R
263#endif
264
Fred Drake699f3522000-06-29 21:12:41 +0000265/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000266#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000267#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000268# define STAT _stati64
269# define FSTAT _fstati64
270# define STRUCT_STAT struct _stati64
271#else
272# define STAT stat
273# define FSTAT fstat
274# define STRUCT_STAT struct stat
275#endif
276
277
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
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000363#ifdef MS_WIN32
364static 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.)
369 This would however require an additional param to the
370 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
429 sprintf(msgbuf, "unknown OS error #%d", errorcode);
430
431 return msgbuf;
432}
433
434/* Set an OS/2-specific error and return NULL. OS/2 kernel
435 errors are not in a global variable e.g. 'errno' nor are
436 they congruent with posix error numbers. */
437
438static PyObject * os2_error(int code)
439{
440 char text[1024];
441 PyObject *v;
442
443 os2_strerror(text, sizeof(text), code, "");
444
445 v = Py_BuildValue("(is)", code, text);
446 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000447 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000448 Py_DECREF(v);
449 }
450 return NULL; /* Signal to Python that an Exception is Pending */
451}
452
453#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000454
455/* POSIX generic methods */
456
Barry Warsaw53699e91996-12-10 23:23:01 +0000457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000458posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000459{
460 int fd;
461 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000462 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000463 return NULL;
464 Py_BEGIN_ALLOW_THREADS
465 res = (*func)(fd);
466 Py_END_ALLOW_THREADS
467 if (res < 0)
468 return posix_error();
469 Py_INCREF(Py_None);
470 return Py_None;
471}
472
473
474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000475posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000476{
Mark Hammondef8b6542001-05-13 08:04:26 +0000477 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000478 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000479 if (!PyArg_ParseTuple(args, format,
480 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000482 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000483 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000484 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000486 return posix_error_with_allocated_filename(path1);
487 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000488 Py_INCREF(Py_None);
489 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000490}
491
Barry Warsaw53699e91996-12-10 23:23:01 +0000492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000493posix_2str(PyObject *args, char *format,
494 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000495{
Mark Hammondef8b6542001-05-13 08:04:26 +0000496 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000497 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000498 if (!PyArg_ParseTuple(args, format,
499 Py_FileSystemDefaultEncoding, &path1,
500 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000502 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000503 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000504 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000505 PyMem_Free(path1);
506 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000507 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000508 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000510 Py_INCREF(Py_None);
511 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000512}
513
Fred Drake699f3522000-06-29 21:12:41 +0000514/* pack a system stat C structure into the Python stat tuple
515 (used by posix_stat() and posix_fstat()) */
516static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000517_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000518{
519 PyObject *v = PyTuple_New(10);
520 if (v == NULL)
521 return NULL;
522
523 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
524#ifdef HAVE_LARGEFILE_SUPPORT
525 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
526#else
527 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
528#endif
529#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
530 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
531#else
532 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
533#endif
534 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
535 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
536 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
537#ifdef HAVE_LARGEFILE_SUPPORT
538 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
539#else
540 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
541#endif
542#if SIZEOF_TIME_T > SIZEOF_LONG
543 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
544 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
545 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
546#else
547 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
548 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
549 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
550#endif
551
552 if (PyErr_Occurred()) {
553 Py_DECREF(v);
554 return NULL;
555 }
556
557 return v;
558}
559
560
Barry Warsaw53699e91996-12-10 23:23:01 +0000561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000562posix_do_stat(PyObject *self, PyObject *args, char *format,
563 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000564{
Fred Drake699f3522000-06-29 21:12:41 +0000565 STRUCT_STAT st;
Mark Hammondef8b6542001-05-13 08:04:26 +0000566 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000567 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000568
569#ifdef MS_WIN32
570 int pathlen;
571 char pathcopy[MAX_PATH];
572#endif /* MS_WIN32 */
573
Mark Hammondef8b6542001-05-13 08:04:26 +0000574 if (!PyArg_ParseTuple(args, format,
575 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000576 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000577
578#ifdef MS_WIN32
579 pathlen = strlen(path);
580 /* the library call can blow up if the file name is too long! */
581 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000582 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000583 errno = ENAMETOOLONG;
584 return posix_error();
585 }
586
587 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000588 /* exception for specific or current drive root */
589 if (!((pathlen == 1) ||
590 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000591 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000592 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000593 {
594 strncpy(pathcopy, path, pathlen);
595 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
596 path = pathcopy;
597 }
598 }
599#endif /* MS_WIN32 */
600
Barry Warsaw53699e91996-12-10 23:23:01 +0000601 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000602 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000603 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000604 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000605 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000606
Mark Hammondef8b6542001-05-13 08:04:26 +0000607 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000608 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000609}
610
611
612/* POSIX methods */
613
Guido van Rossum94f6f721999-01-06 18:42:14 +0000614static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000615"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000616Test for access to a file.";
617
618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000619posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000620{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000621 char *path;
622 int mode;
623 int res;
624
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000625 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000626 return NULL;
627 Py_BEGIN_ALLOW_THREADS
628 res = access(path, mode);
629 Py_END_ALLOW_THREADS
630 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000631}
632
Guido van Rossumd371ff11999-01-25 16:12:23 +0000633#ifndef F_OK
634#define F_OK 0
635#endif
636#ifndef R_OK
637#define R_OK 4
638#endif
639#ifndef W_OK
640#define W_OK 2
641#endif
642#ifndef X_OK
643#define X_OK 1
644#endif
645
646#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000647static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000648"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000649Return the name of the terminal device connected to 'fd'.";
650
651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000652posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000653{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000654 int id;
655 char *ret;
656
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000657 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000658 return NULL;
659
Guido van Rossum94f6f721999-01-06 18:42:14 +0000660 ret = ttyname(id);
661 if (ret == NULL)
662 return(posix_error());
663 return(PyString_FromString(ret));
664}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000665#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000666
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000667#ifdef HAVE_CTERMID
668static char posix_ctermid__doc__[] =
669"ctermid() -> String\n\
670Return the name of the controlling terminal for this process.";
671
672static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000673posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000674{
675 char *ret;
676 char buffer[L_ctermid];
677
678 if (!PyArg_ParseTuple(args, ":ctermid"))
679 return NULL;
680
Greg Wardb48bc172000-03-01 21:51:56 +0000681#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000682 ret = ctermid_r(buffer);
683#else
684 ret = ctermid(buffer);
685#endif
686 if (ret == NULL)
687 return(posix_error());
688 return(PyString_FromString(buffer));
689}
690#endif
691
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000692static char posix_chdir__doc__[] =
693"chdir(path) -> None\n\
694Change the current working directory to the specified path.";
695
Barry Warsaw53699e91996-12-10 23:23:01 +0000696static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000697posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000698{
Mark Hammondef8b6542001-05-13 08:04:26 +0000699 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000700}
701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000702
703static char posix_chmod__doc__[] =
704"chmod(path, mode) -> None\n\
705Change the access permissions of a file.";
706
Barry Warsaw53699e91996-12-10 23:23:01 +0000707static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000708posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000709{
Mark Hammondef8b6542001-05-13 08:04:26 +0000710 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000711 int i;
712 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000713 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
714 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000715 return NULL;
716 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000717 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000718 Py_END_ALLOW_THREADS
719 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000720 return posix_error_with_allocated_filename(path);
721 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000722 Py_INCREF(Py_None);
723 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724}
725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000726
Martin v. Löwis244edc82001-10-04 22:44:26 +0000727#ifdef HAVE_CHROOT
728static char posix_chroot__doc__[] =
729"chroot(path) -> None\n\
730Change root directory to path.";
731
732static PyObject *
733posix_chroot(PyObject *self, PyObject *args)
734{
735 return posix_1str(args, "et:chroot", chroot);
736}
737#endif
738
Guido van Rossum21142a01999-01-08 21:05:37 +0000739#ifdef HAVE_FSYNC
740static char posix_fsync__doc__[] =
741"fsync(fildes) -> None\n\
742force write of file with filedescriptor to disk.";
743
744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000745posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000746{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000747 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000748}
749#endif /* HAVE_FSYNC */
750
751#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000752
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000753#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000754extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
755#endif
756
Guido van Rossum21142a01999-01-08 21:05:37 +0000757static char posix_fdatasync__doc__[] =
758"fdatasync(fildes) -> None\n\
759force write of file with filedescriptor to disk.\n\
760 does not force update of metadata.";
761
762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000763posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000764{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000765 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000766}
767#endif /* HAVE_FDATASYNC */
768
769
Fredrik Lundh10723342000-07-10 16:38:09 +0000770#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000771static char posix_chown__doc__[] =
772"chown(path, uid, gid) -> None\n\
773Change the owner and group id of path to the numeric uid and gid.";
774
Barry Warsaw53699e91996-12-10 23:23:01 +0000775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000776posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000777{
Mark Hammondef8b6542001-05-13 08:04:26 +0000778 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000779 int uid, gid;
780 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000781 if (!PyArg_ParseTuple(args, "etii:chown",
782 Py_FileSystemDefaultEncoding, &path,
783 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000784 return NULL;
785 Py_BEGIN_ALLOW_THREADS
786 res = chown(path, (uid_t) uid, (gid_t) gid);
787 Py_END_ALLOW_THREADS
788 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000789 return posix_error_with_allocated_filename(path);
790 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000791 Py_INCREF(Py_None);
792 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000793}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000794#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000796
Guido van Rossum36bc6801995-06-14 22:54:23 +0000797#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000798static char posix_getcwd__doc__[] =
799"getcwd() -> path\n\
800Return a string representing the current working directory.";
801
Barry Warsaw53699e91996-12-10 23:23:01 +0000802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000803posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000804{
805 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000806 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000807 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000808 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000809 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000810 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000811 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000812 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000814 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000815}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000816#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000818
Guido van Rossumb6775db1994-08-01 11:34:53 +0000819#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000820static char posix_link__doc__[] =
821"link(src, dst) -> None\n\
822Create a hard link to a file.";
823
Barry Warsaw53699e91996-12-10 23:23:01 +0000824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000825posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000826{
Mark Hammondef8b6542001-05-13 08:04:26 +0000827 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000828}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000829#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000830
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000831
832static char posix_listdir__doc__[] =
833"listdir(path) -> list_of_strings\n\
834Return a list containing the names of the entries in the directory.\n\
835\n\
836 path: path of directory to list\n\
837\n\
838The list is in arbitrary order. It does not include the special\n\
839entries '.' and '..' even if they are present in the directory.";
840
Barry Warsaw53699e91996-12-10 23:23:01 +0000841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000842posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000843{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000844 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000845 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000846#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000847
Barry Warsaw53699e91996-12-10 23:23:01 +0000848 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000849 HANDLE hFindFile;
850 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000851 /* MAX_PATH characters could mean a bigger encoded string */
852 char namebuf[MAX_PATH*2+5];
853 char *bufptr = namebuf;
854 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000855 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000856
Mark Hammondef8b6542001-05-13 08:04:26 +0000857 if (!PyArg_ParseTuple(args, "et#:listdir",
858 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000859 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000860 ch = namebuf[len-1];
861 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000862 namebuf[len++] = '/';
863 strcpy(namebuf + len, "*.*");
864
Barry Warsaw53699e91996-12-10 23:23:01 +0000865 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000866 return NULL;
867
868 hFindFile = FindFirstFile(namebuf, &FileData);
869 if (hFindFile == INVALID_HANDLE_VALUE) {
870 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000871 if (errno == ERROR_FILE_NOT_FOUND)
872 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000873 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000874 }
875 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000876 if (FileData.cFileName[0] == '.' &&
877 (FileData.cFileName[1] == '\0' ||
878 FileData.cFileName[1] == '.' &&
879 FileData.cFileName[2] == '\0'))
880 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000881 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000882 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000883 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000884 d = NULL;
885 break;
886 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000887 if (PyList_Append(d, v) != 0) {
888 Py_DECREF(v);
889 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000890 d = NULL;
891 break;
892 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000893 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000894 } while (FindNextFile(hFindFile, &FileData) == TRUE);
895
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000896 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +0000897 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000898
899 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000900
Tim Peters0bb44a42000-09-15 07:44:49 +0000901#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000902
903#ifndef MAX_PATH
904#define MAX_PATH 250
905#endif
906 char *name, *pt;
907 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000908 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000909 char namebuf[MAX_PATH+5];
910 struct _find_t ep;
911
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000912 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000913 return NULL;
914 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000915 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000916 return NULL;
917 }
918 strcpy(namebuf, name);
919 for (pt = namebuf; *pt; pt++)
920 if (*pt == '/')
921 *pt = '\\';
922 if (namebuf[len-1] != '\\')
923 namebuf[len++] = '\\';
924 strcpy(namebuf + len, "*.*");
925
Barry Warsaw53699e91996-12-10 23:23:01 +0000926 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000927 return NULL;
928
929 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000930 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
931 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000932 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000933 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000934 }
935 do {
936 if (ep.name[0] == '.' &&
937 (ep.name[1] == '\0' ||
938 ep.name[1] == '.' &&
939 ep.name[2] == '\0'))
940 continue;
941 strcpy(namebuf, ep.name);
942 for (pt = namebuf; *pt; pt++)
943 if (isupper(*pt))
944 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000945 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000946 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000947 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000948 d = NULL;
949 break;
950 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000951 if (PyList_Append(d, v) != 0) {
952 Py_DECREF(v);
953 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000954 d = NULL;
955 break;
956 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000957 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000958 } while (_dos_findnext(&ep) == 0);
959
960 return d;
961
Tim Peters0bb44a42000-09-15 07:44:49 +0000962#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963
964#ifndef MAX_PATH
965#define MAX_PATH CCHMAXPATH
966#endif
967 char *name, *pt;
968 int len;
969 PyObject *d, *v;
970 char namebuf[MAX_PATH+5];
971 HDIR hdir = 1;
972 ULONG srchcnt = 1;
973 FILEFINDBUF3 ep;
974 APIRET rc;
975
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000976 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000977 return NULL;
978 if (len >= MAX_PATH) {
979 PyErr_SetString(PyExc_ValueError, "path too long");
980 return NULL;
981 }
982 strcpy(namebuf, name);
983 for (pt = namebuf; *pt; pt++)
984 if (*pt == '/')
985 *pt = '\\';
986 if (namebuf[len-1] != '\\')
987 namebuf[len++] = '\\';
988 strcpy(namebuf + len, "*.*");
989
990 if ((d = PyList_New(0)) == NULL)
991 return NULL;
992
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000993 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
994 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000995 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000996 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
997 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
998 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000999
1000 if (rc != NO_ERROR) {
1001 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001002 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001003 }
1004
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001005 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001006 do {
1007 if (ep.achName[0] == '.'
1008 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001009 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001010
1011 strcpy(namebuf, ep.achName);
1012
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001013 /* Leave Case of Name Alone -- In Native Form */
1014 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001015
1016 v = PyString_FromString(namebuf);
1017 if (v == NULL) {
1018 Py_DECREF(d);
1019 d = NULL;
1020 break;
1021 }
1022 if (PyList_Append(d, v) != 0) {
1023 Py_DECREF(v);
1024 Py_DECREF(d);
1025 d = NULL;
1026 break;
1027 }
1028 Py_DECREF(v);
1029 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1030 }
1031
1032 return d;
1033#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001034
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001035 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001036 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001037 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001038 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001039 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001040 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001041 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001042 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001043 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001044 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001045 closedir(dirp);
1046 return NULL;
1047 }
1048 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001049 if (ep->d_name[0] == '.' &&
1050 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001051 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001052 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001053 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001054 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001055 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001056 d = NULL;
1057 break;
1058 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001059 if (PyList_Append(d, v) != 0) {
1060 Py_DECREF(v);
1061 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001062 d = NULL;
1063 break;
1064 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001065 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001066 }
1067 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001068
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001069 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001070
Tim Peters0bb44a42000-09-15 07:44:49 +00001071#endif /* which OS */
1072} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001073
Mark Hammondef8b6542001-05-13 08:04:26 +00001074#ifdef MS_WIN32
1075/* A helper function for abspath on win32 */
1076static PyObject *
1077posix__getfullpathname(PyObject *self, PyObject *args)
1078{
1079 /* assume encoded strings wont more than double no of chars */
1080 char inbuf[MAX_PATH*2];
1081 char *inbufp = inbuf;
1082 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1083 char outbuf[MAX_PATH*2];
1084 char *temp;
1085 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1086 Py_FileSystemDefaultEncoding, &inbufp,
1087 &insize))
1088 return NULL;
1089 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1090 outbuf, &temp))
1091 return win32_error("GetFullPathName", inbuf);
1092 return PyString_FromString(outbuf);
1093} /* end of posix__getfullpathname */
1094#endif /* MS_WIN32 */
1095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001096static char posix_mkdir__doc__[] =
1097"mkdir(path [, mode=0777]) -> None\n\
1098Create a directory.";
1099
Barry Warsaw53699e91996-12-10 23:23:01 +00001100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001101posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001102{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001103 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001104 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001105 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001106 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1107 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001108 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001109 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001110#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001111 res = mkdir(path);
1112#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001113 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001114#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001115 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001116 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001117 return posix_error_with_allocated_filename(path);
1118 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001119 Py_INCREF(Py_None);
1120 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001121}
1122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001123
Guido van Rossumb6775db1994-08-01 11:34:53 +00001124#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001125#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1126#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1127#include <sys/resource.h>
1128#endif
1129#endif
1130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001131static char posix_nice__doc__[] =
1132"nice(inc) -> new_priority\n\
1133Decrease the priority of process and return new priority.";
1134
Barry Warsaw53699e91996-12-10 23:23:01 +00001135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001136posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001137{
1138 int increment, value;
1139
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001140 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001141 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001142
1143 /* There are two flavours of 'nice': one that returns the new
1144 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001145 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1146 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001147
1148 If we are of the nice family that returns the new priority, we
1149 need to clear errno before the call, and check if errno is filled
1150 before calling posix_error() on a returnvalue of -1, because the
1151 -1 may be the actual new priority! */
1152
1153 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001154 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001155#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001156 if (value == 0)
1157 value = getpriority(PRIO_PROCESS, 0);
1158#endif
1159 if (value == -1 && errno != 0)
1160 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001161 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001162 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001163}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001164#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001165
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001166
1167static char posix_rename__doc__[] =
1168"rename(old, new) -> None\n\
1169Rename a file or directory.";
1170
Barry Warsaw53699e91996-12-10 23:23:01 +00001171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001172posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001173{
Mark Hammondef8b6542001-05-13 08:04:26 +00001174 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001175}
1176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001177
1178static char posix_rmdir__doc__[] =
1179"rmdir(path) -> None\n\
1180Remove a directory.";
1181
Barry Warsaw53699e91996-12-10 23:23:01 +00001182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001183posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184{
Mark Hammondef8b6542001-05-13 08:04:26 +00001185 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001186}
1187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001188
1189static char posix_stat__doc__[] =
1190"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1191Perform a stat system call on the given path.";
1192
Barry Warsaw53699e91996-12-10 23:23:01 +00001193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001194posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195{
Mark Hammondef8b6542001-05-13 08:04:26 +00001196 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001197}
1198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001199
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001200#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001201static char posix_system__doc__[] =
1202"system(command) -> exit_status\n\
1203Execute the command (a string) in a subshell.";
1204
Barry Warsaw53699e91996-12-10 23:23:01 +00001205static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001206posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001207{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001208 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001209 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001210 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001212 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001213 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001214 Py_END_ALLOW_THREADS
1215 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001216}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001217#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001219
1220static char posix_umask__doc__[] =
1221"umask(new_mask) -> old_mask\n\
1222Set the current numeric umask and return the previous umask.";
1223
Barry Warsaw53699e91996-12-10 23:23:01 +00001224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001225posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226{
1227 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001228 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001229 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001230 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001231 if (i < 0)
1232 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001233 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001234}
1235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001236
1237static char posix_unlink__doc__[] =
1238"unlink(path) -> None\n\
1239Remove a file (same as remove(path)).";
1240
1241static char posix_remove__doc__[] =
1242"remove(path) -> None\n\
1243Remove a file (same as unlink(path)).";
1244
Barry Warsaw53699e91996-12-10 23:23:01 +00001245static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001246posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001247{
Mark Hammondef8b6542001-05-13 08:04:26 +00001248 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249}
1250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001251
Guido van Rossumb6775db1994-08-01 11:34:53 +00001252#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001253static char posix_uname__doc__[] =
1254"uname() -> (sysname, nodename, release, version, machine)\n\
1255Return a tuple identifying the current operating system.";
1256
Barry Warsaw53699e91996-12-10 23:23:01 +00001257static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001258posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001259{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001260 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001261 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001262 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001263 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001264 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001265 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001266 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001267 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001268 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001269 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001270 u.sysname,
1271 u.nodename,
1272 u.release,
1273 u.version,
1274 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001275}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001276#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001278
1279static char posix_utime__doc__[] =
1280"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001281utime(path, None) -> None\n\
1282Set the access and modified time of the file to the given values. If the\n\
1283second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001284
Barry Warsaw53699e91996-12-10 23:23:01 +00001285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001286posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001287{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001288 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001289 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001290 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001291 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001292
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001293/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001294#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001295 struct utimbuf buf;
1296#define ATIME buf.actime
1297#define MTIME buf.modtime
1298#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001299#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001300 time_t buf[2];
1301#define ATIME buf[0]
1302#define MTIME buf[1]
1303#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001304#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001305
Barry Warsaw3cef8562000-05-01 16:17:24 +00001306 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001307 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001308 if (arg == Py_None) {
1309 /* optional time values not given */
1310 Py_BEGIN_ALLOW_THREADS
1311 res = utime(path, NULL);
1312 Py_END_ALLOW_THREADS
1313 }
1314 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1315 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001316 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001317 return NULL;
1318 }
1319 else {
1320 ATIME = atime;
1321 MTIME = mtime;
1322 Py_BEGIN_ALLOW_THREADS
1323 res = utime(path, UTIME_ARG);
1324 Py_END_ALLOW_THREADS
1325 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001326 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001327 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001328 Py_INCREF(Py_None);
1329 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001330#undef UTIME_ARG
1331#undef ATIME
1332#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333}
1334
Guido van Rossum85e3b011991-06-03 12:42:10 +00001335
Guido van Rossum3b066191991-06-04 19:40:25 +00001336/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001337
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001338static char posix__exit__doc__[] =
1339"_exit(status)\n\
1340Exit to the system with specified status, without normal exit processing.";
1341
Barry Warsaw53699e91996-12-10 23:23:01 +00001342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001343posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001344{
1345 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001346 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001347 return NULL;
1348 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001349 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001350}
1351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001352
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001353#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001354static char posix_execv__doc__[] =
1355"execv(path, args)\n\
1356Execute an executable path with arguments, replacing current process.\n\
1357\n\
1358 path: path of executable file\n\
1359 args: tuple or list of strings";
1360
Barry Warsaw53699e91996-12-10 23:23:01 +00001361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001362posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001363{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001364 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001365 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001366 char **argvlist;
1367 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001368 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001369
Guido van Rossum89b33251993-10-22 14:26:06 +00001370 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001371 argv is a list or tuple of strings. */
1372
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001373 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001374 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001375 if (PyList_Check(argv)) {
1376 argc = PyList_Size(argv);
1377 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001378 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001379 else if (PyTuple_Check(argv)) {
1380 argc = PyTuple_Size(argv);
1381 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001382 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001383 else {
Fred Drake661ea262000-10-24 19:57:45 +00001384 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001385 return NULL;
1386 }
1387
1388 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001389 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001390 return NULL;
1391 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001392
Barry Warsaw53699e91996-12-10 23:23:01 +00001393 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001394 if (argvlist == NULL)
1395 return NULL;
1396 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001397 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1398 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001399 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001400 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001401 return NULL;
1402
Guido van Rossum85e3b011991-06-03 12:42:10 +00001403 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001404 }
1405 argvlist[argc] = NULL;
1406
Guido van Rossumb6775db1994-08-01 11:34:53 +00001407#ifdef BAD_EXEC_PROTOTYPES
1408 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001409#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001410 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001411#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001412
Guido van Rossum85e3b011991-06-03 12:42:10 +00001413 /* If we get here it's definitely an error */
1414
Barry Warsaw53699e91996-12-10 23:23:01 +00001415 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001416 return posix_error();
1417}
1418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001419
1420static char posix_execve__doc__[] =
1421"execve(path, args, env)\n\
1422Execute a path with arguments and environment, replacing current process.\n\
1423\n\
1424 path: path of executable file\n\
1425 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001426 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001427
Barry Warsaw53699e91996-12-10 23:23:01 +00001428static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001429posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001430{
1431 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001432 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001433 char **argvlist;
1434 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001435 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001436 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001437 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001438
1439 /* execve has three arguments: (path, argv, env), where
1440 argv is a list or tuple of strings and env is a dictionary
1441 like posix.environ. */
1442
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001443 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001444 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001445 if (PyList_Check(argv)) {
1446 argc = PyList_Size(argv);
1447 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001448 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001449 else if (PyTuple_Check(argv)) {
1450 argc = PyTuple_Size(argv);
1451 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001452 }
1453 else {
Fred Drake661ea262000-10-24 19:57:45 +00001454 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001455 return NULL;
1456 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001457 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001458 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001459 return NULL;
1460 }
1461
Guido van Rossum50422b42000-04-26 20:34:28 +00001462 if (argc == 0) {
1463 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001464 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001465 return NULL;
1466 }
1467
Barry Warsaw53699e91996-12-10 23:23:01 +00001468 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001469 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001470 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001471 return NULL;
1472 }
1473 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001474 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001475 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001476 &argvlist[i]))
1477 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001478 goto fail_1;
1479 }
1480 }
1481 argvlist[argc] = NULL;
1482
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001483 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001484 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001485 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001486 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001487 goto fail_1;
1488 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001489 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001490 keys = PyMapping_Keys(env);
1491 vals = PyMapping_Values(env);
1492 if (!keys || !vals)
1493 goto fail_2;
1494
1495 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001496 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001497
1498 key = PyList_GetItem(keys, pos);
1499 val = PyList_GetItem(vals, pos);
1500 if (!key || !val)
1501 goto fail_2;
1502
Fred Drake661ea262000-10-24 19:57:45 +00001503 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1504 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001505 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001506 goto fail_2;
1507 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001508
1509#if defined(PYOS_OS2)
1510 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1511 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1512#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001513 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001514 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001515 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001516 goto fail_2;
1517 }
1518 sprintf(p, "%s=%s", k, v);
1519 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001520#if defined(PYOS_OS2)
1521 }
1522#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001523 }
1524 envlist[envc] = 0;
1525
Guido van Rossumb6775db1994-08-01 11:34:53 +00001526
1527#ifdef BAD_EXEC_PROTOTYPES
1528 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001529#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001530 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001531#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001532
1533 /* If we get here it's definitely an error */
1534
1535 (void) posix_error();
1536
1537 fail_2:
1538 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001539 PyMem_DEL(envlist[envc]);
1540 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001541 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001542 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001543 Py_XDECREF(vals);
1544 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001545 return NULL;
1546}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001547#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001548
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001549
Guido van Rossuma1065681999-01-25 23:20:23 +00001550#ifdef HAVE_SPAWNV
1551static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001552"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001553Execute an executable path with arguments, replacing current process.\n\
1554\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001555 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001556 path: path of executable file\n\
1557 args: tuple or list of strings";
1558
1559static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001560posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001561{
1562 char *path;
1563 PyObject *argv;
1564 char **argvlist;
1565 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001566 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001567 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001568
1569 /* spawnv has three arguments: (mode, path, argv), where
1570 argv is a list or tuple of strings. */
1571
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001572 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001573 return NULL;
1574 if (PyList_Check(argv)) {
1575 argc = PyList_Size(argv);
1576 getitem = PyList_GetItem;
1577 }
1578 else if (PyTuple_Check(argv)) {
1579 argc = PyTuple_Size(argv);
1580 getitem = PyTuple_GetItem;
1581 }
1582 else {
Fred Drake661ea262000-10-24 19:57:45 +00001583 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001584 return NULL;
1585 }
1586
1587 argvlist = PyMem_NEW(char *, argc+1);
1588 if (argvlist == NULL)
1589 return NULL;
1590 for (i = 0; i < argc; i++) {
1591 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1592 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001593 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001594 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001595 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001596 }
1597 }
1598 argvlist[argc] = NULL;
1599
Guido van Rossum246bc171999-02-01 23:54:31 +00001600 if (mode == _OLD_P_OVERLAY)
1601 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001602 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001603
1604 PyMem_DEL(argvlist);
1605
Fred Drake699f3522000-06-29 21:12:41 +00001606 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001607 return posix_error();
1608 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001609#if SIZEOF_LONG == SIZEOF_VOID_P
1610 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001611#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001612 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001613#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001614}
1615
1616
1617static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001618"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001619Execute a path with arguments and environment, replacing current process.\n\
1620\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001621 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001622 path: path of executable file\n\
1623 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001624 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001625
1626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001627posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001628{
1629 char *path;
1630 PyObject *argv, *env;
1631 char **argvlist;
1632 char **envlist;
1633 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1634 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001635 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001636 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001637
1638 /* spawnve has four arguments: (mode, path, argv, env), where
1639 argv is a list or tuple of strings and env is a dictionary
1640 like posix.environ. */
1641
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001642 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001643 return NULL;
1644 if (PyList_Check(argv)) {
1645 argc = PyList_Size(argv);
1646 getitem = PyList_GetItem;
1647 }
1648 else if (PyTuple_Check(argv)) {
1649 argc = PyTuple_Size(argv);
1650 getitem = PyTuple_GetItem;
1651 }
1652 else {
Fred Drake661ea262000-10-24 19:57:45 +00001653 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001654 return NULL;
1655 }
1656 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001657 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001658 return NULL;
1659 }
1660
1661 argvlist = PyMem_NEW(char *, argc+1);
1662 if (argvlist == NULL) {
1663 PyErr_NoMemory();
1664 return NULL;
1665 }
1666 for (i = 0; i < argc; i++) {
1667 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001668 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001669 &argvlist[i]))
1670 {
1671 goto fail_1;
1672 }
1673 }
1674 argvlist[argc] = NULL;
1675
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001676 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001677 envlist = PyMem_NEW(char *, i + 1);
1678 if (envlist == NULL) {
1679 PyErr_NoMemory();
1680 goto fail_1;
1681 }
1682 envc = 0;
1683 keys = PyMapping_Keys(env);
1684 vals = PyMapping_Values(env);
1685 if (!keys || !vals)
1686 goto fail_2;
1687
1688 for (pos = 0; pos < i; pos++) {
1689 char *p, *k, *v;
1690
1691 key = PyList_GetItem(keys, pos);
1692 val = PyList_GetItem(vals, pos);
1693 if (!key || !val)
1694 goto fail_2;
1695
Fred Drake661ea262000-10-24 19:57:45 +00001696 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1697 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001698 {
1699 goto fail_2;
1700 }
1701 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1702 if (p == NULL) {
1703 PyErr_NoMemory();
1704 goto fail_2;
1705 }
1706 sprintf(p, "%s=%s", k, v);
1707 envlist[envc++] = p;
1708 }
1709 envlist[envc] = 0;
1710
Guido van Rossum246bc171999-02-01 23:54:31 +00001711 if (mode == _OLD_P_OVERLAY)
1712 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001713 spawnval = _spawnve(mode, path, argvlist, envlist);
1714 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001715 (void) posix_error();
1716 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001717#if SIZEOF_LONG == SIZEOF_VOID_P
1718 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001719#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001720 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001721#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001722
1723 fail_2:
1724 while (--envc >= 0)
1725 PyMem_DEL(envlist[envc]);
1726 PyMem_DEL(envlist);
1727 fail_1:
1728 PyMem_DEL(argvlist);
1729 Py_XDECREF(vals);
1730 Py_XDECREF(keys);
1731 return res;
1732}
1733#endif /* HAVE_SPAWNV */
1734
1735
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001736#ifdef HAVE_FORK1
1737static char posix_fork1__doc__[] =
1738"fork1() -> pid\n\
1739Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1740\n\
1741Return 0 to child process and PID of child to parent process.";
1742
1743static PyObject *
1744posix_fork1(self, args)
1745 PyObject *self;
1746 PyObject *args;
1747{
1748 int pid;
1749 if (!PyArg_ParseTuple(args, ":fork1"))
1750 return NULL;
1751 pid = fork1();
1752 if (pid == -1)
1753 return posix_error();
1754 PyOS_AfterFork();
1755 return PyInt_FromLong((long)pid);
1756}
1757#endif
1758
1759
Guido van Rossumad0ee831995-03-01 10:34:45 +00001760#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001761static char posix_fork__doc__[] =
1762"fork() -> pid\n\
1763Fork a child process.\n\
1764\n\
1765Return 0 to child process and PID of child to parent process.";
1766
Barry Warsaw53699e91996-12-10 23:23:01 +00001767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001768posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001769{
1770 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001771 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001772 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001773 pid = fork();
1774 if (pid == -1)
1775 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001776 if (pid == 0)
1777 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001778 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001779}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001780#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001781
Fred Drake8cef4cf2000-06-28 16:40:38 +00001782#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1783#ifdef HAVE_PTY_H
1784#include <pty.h>
1785#else
1786#ifdef HAVE_LIBUTIL_H
1787#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001788#endif /* HAVE_LIBUTIL_H */
1789#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001790#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001791
Thomas Wouters70c21a12000-07-14 14:28:33 +00001792#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001793static char posix_openpty__doc__[] =
1794"openpty() -> (master_fd, slave_fd)\n\
1795Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1796
1797static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001798posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001799{
1800 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001801#ifndef HAVE_OPENPTY
1802 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001803#endif
1804
Fred Drake8cef4cf2000-06-28 16:40:38 +00001805 if (!PyArg_ParseTuple(args, ":openpty"))
1806 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001807
1808#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001809 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1810 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001811#else
1812 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1813 if (slave_name == NULL)
1814 return posix_error();
1815
1816 slave_fd = open(slave_name, O_RDWR);
1817 if (slave_fd < 0)
1818 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001819#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001820
Fred Drake8cef4cf2000-06-28 16:40:38 +00001821 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001822
Fred Drake8cef4cf2000-06-28 16:40:38 +00001823}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001824#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001825
1826#ifdef HAVE_FORKPTY
1827static char posix_forkpty__doc__[] =
1828"forkpty() -> (pid, master_fd)\n\
1829Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1830Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1831To both, return fd of newly opened pseudo-terminal.\n";
1832
1833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001834posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001835{
1836 int master_fd, pid;
1837
1838 if (!PyArg_ParseTuple(args, ":forkpty"))
1839 return NULL;
1840 pid = forkpty(&master_fd, NULL, NULL, NULL);
1841 if (pid == -1)
1842 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001843 if (pid == 0)
1844 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001845 return Py_BuildValue("(ii)", pid, master_fd);
1846}
1847#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001848
Guido van Rossumad0ee831995-03-01 10:34:45 +00001849#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001850static char posix_getegid__doc__[] =
1851"getegid() -> egid\n\
1852Return the current process's effective group id.";
1853
Barry Warsaw53699e91996-12-10 23:23:01 +00001854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001855posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001856{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001857 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001858 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001859 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001860}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001861#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001862
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001863
Guido van Rossumad0ee831995-03-01 10:34:45 +00001864#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001865static char posix_geteuid__doc__[] =
1866"geteuid() -> euid\n\
1867Return the current process's effective user id.";
1868
Barry Warsaw53699e91996-12-10 23:23:01 +00001869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001870posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001871{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001872 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001873 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001874 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001875}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001876#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001877
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001878
Guido van Rossumad0ee831995-03-01 10:34:45 +00001879#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001880static char posix_getgid__doc__[] =
1881"getgid() -> gid\n\
1882Return the current process's group id.";
1883
Barry Warsaw53699e91996-12-10 23:23:01 +00001884static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001885posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001886{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001887 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001888 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001889 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001890}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001891#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001892
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001893
1894static char posix_getpid__doc__[] =
1895"getpid() -> pid\n\
1896Return the current process id";
1897
Barry Warsaw53699e91996-12-10 23:23:01 +00001898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001899posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001900{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001901 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001902 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001903 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001904}
1905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001906
Fred Drakec9680921999-12-13 16:37:25 +00001907#ifdef HAVE_GETGROUPS
1908static char posix_getgroups__doc__[] = "\
1909getgroups() -> list of group IDs\n\
1910Return list of supplemental group IDs for the process.";
1911
1912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001913posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001914{
1915 PyObject *result = NULL;
1916
1917 if (PyArg_ParseTuple(args, ":getgroups")) {
1918#ifdef NGROUPS_MAX
1919#define MAX_GROUPS NGROUPS_MAX
1920#else
1921 /* defined to be 16 on Solaris7, so this should be a small number */
1922#define MAX_GROUPS 64
1923#endif
1924 gid_t grouplist[MAX_GROUPS];
1925 int n;
1926
1927 n = getgroups(MAX_GROUPS, grouplist);
1928 if (n < 0)
1929 posix_error();
1930 else {
1931 result = PyList_New(n);
1932 if (result != NULL) {
1933 PyObject *o;
1934 int i;
1935 for (i = 0; i < n; ++i) {
1936 o = PyInt_FromLong((long)grouplist[i]);
1937 if (o == NULL) {
1938 Py_DECREF(result);
1939 result = NULL;
1940 break;
1941 }
1942 PyList_SET_ITEM(result, i, o);
1943 }
1944 }
1945 }
1946 }
1947 return result;
1948}
1949#endif
1950
Guido van Rossumb6775db1994-08-01 11:34:53 +00001951#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001952static char posix_getpgrp__doc__[] =
1953"getpgrp() -> pgrp\n\
1954Return the current process group id.";
1955
Barry Warsaw53699e91996-12-10 23:23:01 +00001956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001957posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001958{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001959 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001960 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001961#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001962 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001963#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001964 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001965#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001966}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001967#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001969
Guido van Rossumb6775db1994-08-01 11:34:53 +00001970#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001971static char posix_setpgrp__doc__[] =
1972"setpgrp() -> None\n\
1973Make this process a session leader.";
1974
Barry Warsaw53699e91996-12-10 23:23:01 +00001975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001976posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001977{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001978 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001979 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001980#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001981 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001982#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001983 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001984#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001985 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001986 Py_INCREF(Py_None);
1987 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001988}
1989
Guido van Rossumb6775db1994-08-01 11:34:53 +00001990#endif /* HAVE_SETPGRP */
1991
Guido van Rossumad0ee831995-03-01 10:34:45 +00001992#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001993static char posix_getppid__doc__[] =
1994"getppid() -> ppid\n\
1995Return the parent's process id.";
1996
Barry Warsaw53699e91996-12-10 23:23:01 +00001997static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001998posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001999{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002000 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002001 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002002 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002003}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002004#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002006
Fred Drake12c6e2d1999-12-14 21:25:03 +00002007#ifdef HAVE_GETLOGIN
2008static char posix_getlogin__doc__[] = "\
2009getlogin() -> string\n\
2010Return the actual login name.";
2011
2012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002013posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002014{
2015 PyObject *result = NULL;
2016
2017 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002018 char *name;
2019 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002020
Fred Drakea30680b2000-12-06 21:24:28 +00002021 errno = 0;
2022 name = getlogin();
2023 if (name == NULL) {
2024 if (errno)
2025 posix_error();
2026 else
2027 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002028 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002029 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002030 else
2031 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002032 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002033 }
2034 return result;
2035}
2036#endif
2037
Guido van Rossumad0ee831995-03-01 10:34:45 +00002038#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002039static char posix_getuid__doc__[] =
2040"getuid() -> uid\n\
2041Return the current process's user id.";
2042
Barry Warsaw53699e91996-12-10 23:23:01 +00002043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002044posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002045{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002046 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002047 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002048 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002049}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002050#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002051
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002052
Guido van Rossumad0ee831995-03-01 10:34:45 +00002053#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002054static char posix_kill__doc__[] =
2055"kill(pid, sig) -> None\n\
2056Kill a process with a signal.";
2057
Barry Warsaw53699e91996-12-10 23:23:01 +00002058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002059posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002060{
2061 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002062 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002063 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002064#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002065 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2066 APIRET rc;
2067 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002068 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002069
2070 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2071 APIRET rc;
2072 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002073 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074
2075 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002076 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002077#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002078 if (kill(pid, sig) == -1)
2079 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002080#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002081 Py_INCREF(Py_None);
2082 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002083}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002084#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002085
Guido van Rossumc0125471996-06-28 18:55:32 +00002086#ifdef HAVE_PLOCK
2087
2088#ifdef HAVE_SYS_LOCK_H
2089#include <sys/lock.h>
2090#endif
2091
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002092static char posix_plock__doc__[] =
2093"plock(op) -> None\n\
2094Lock program segments into memory.";
2095
Barry Warsaw53699e91996-12-10 23:23:01 +00002096static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002097posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002098{
2099 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002100 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002101 return NULL;
2102 if (plock(op) == -1)
2103 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002104 Py_INCREF(Py_None);
2105 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002106}
2107#endif
2108
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002109
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002110#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002111static char posix_popen__doc__[] =
2112"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2113Open a pipe to/from a command returning a file object.";
2114
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002115#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002116static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002117async_system(const char *command)
2118{
2119 char *p, errormsg[256], args[1024];
2120 RESULTCODES rcodes;
2121 APIRET rc;
2122 char *shell = getenv("COMSPEC");
2123 if (!shell)
2124 shell = "cmd";
2125
2126 strcpy(args, shell);
2127 p = &args[ strlen(args)+1 ];
2128 strcpy(p, "/c ");
2129 strcat(p, command);
2130 p += strlen(p) + 1;
2131 *p = '\0';
2132
2133 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002134 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002135 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002136 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002137 &rcodes, shell);
2138 return rc;
2139}
2140
Guido van Rossumd48f2521997-12-05 22:19:34 +00002141static FILE *
2142popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002143{
2144 HFILE rhan, whan;
2145 FILE *retfd = NULL;
2146 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2147
Guido van Rossumd48f2521997-12-05 22:19:34 +00002148 if (rc != NO_ERROR) {
2149 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002150 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002151 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002152
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002153 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2154 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002155
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002156 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2157 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002158
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002159 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2160 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002161
2162 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002163 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002164 }
2165
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002166 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2167 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002168
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002169 close(oldfd); /* And Close Saved STDOUT Handle */
2170 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002171
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002172 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2173 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002174
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002175 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2176 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002177
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002178 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2179 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002180
2181 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002182 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002183 }
2184
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002185 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2186 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002187
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002188 close(oldfd); /* And Close Saved STDIN Handle */
2189 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002190
Guido van Rossumd48f2521997-12-05 22:19:34 +00002191 } else {
2192 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002193 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002194 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002195}
2196
2197static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002198posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002199{
2200 char *name;
2201 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002202 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002203 FILE *fp;
2204 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002205 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002206 return NULL;
2207 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002208 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002209 Py_END_ALLOW_THREADS
2210 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002211 return os2_error(err);
2212
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002213 f = PyFile_FromFile(fp, name, mode, fclose);
2214 if (f != NULL)
2215 PyFile_SetBufSize(f, bufsize);
2216 return f;
2217}
2218
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002219#elif defined(MS_WIN32)
2220
2221/*
2222 * Portable 'popen' replacement for Win32.
2223 *
2224 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2225 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002226 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002227 */
2228
2229#include <malloc.h>
2230#include <io.h>
2231#include <fcntl.h>
2232
2233/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2234#define POPEN_1 1
2235#define POPEN_2 2
2236#define POPEN_3 3
2237#define POPEN_4 4
2238
2239static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002240static int _PyPclose(FILE *file);
2241
2242/*
2243 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002244 * for use when retrieving the process exit code. See _PyPclose() below
2245 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002246 */
2247static PyObject *_PyPopenProcs = NULL;
2248
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002249
2250/* popen that works from a GUI.
2251 *
2252 * The result of this function is a pipe (file) connected to the
2253 * processes stdin or stdout, depending on the requested mode.
2254 */
2255
2256static PyObject *
2257posix_popen(PyObject *self, PyObject *args)
2258{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002259 PyObject *f, *s;
2260 int tm = 0;
2261
2262 char *cmdstring;
2263 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002264 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002265 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002266 return NULL;
2267
2268 s = PyTuple_New(0);
2269
2270 if (*mode == 'r')
2271 tm = _O_RDONLY;
2272 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002273 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002274 return NULL;
2275 } else
2276 tm = _O_WRONLY;
2277
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002278 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002279 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002280 return NULL;
2281 }
2282
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002283 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002284 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002285 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002286 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002287 else
2288 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2289
2290 return f;
2291}
2292
2293/* Variation on win32pipe.popen
2294 *
2295 * The result of this function is a pipe (file) connected to the
2296 * process's stdin, and a pipe connected to the process's stdout.
2297 */
2298
2299static PyObject *
2300win32_popen2(PyObject *self, PyObject *args)
2301{
2302 PyObject *f;
2303 int tm=0;
2304
2305 char *cmdstring;
2306 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002307 int bufsize = -1;
2308 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002309 return NULL;
2310
2311 if (*mode == 't')
2312 tm = _O_TEXT;
2313 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002314 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002315 return NULL;
2316 } else
2317 tm = _O_BINARY;
2318
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002319 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002320 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002321 return NULL;
2322 }
2323
2324 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002325
2326 return f;
2327}
2328
2329/*
2330 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002331 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002332 * The result of this function is 3 pipes - the process's stdin,
2333 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002334 */
2335
2336static PyObject *
2337win32_popen3(PyObject *self, PyObject *args)
2338{
2339 PyObject *f;
2340 int tm = 0;
2341
2342 char *cmdstring;
2343 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002344 int bufsize = -1;
2345 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002346 return NULL;
2347
2348 if (*mode == 't')
2349 tm = _O_TEXT;
2350 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002351 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002352 return NULL;
2353 } else
2354 tm = _O_BINARY;
2355
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002356 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002357 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002358 return NULL;
2359 }
2360
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002361 f = _PyPopen(cmdstring, tm, POPEN_3);
2362
2363 return f;
2364}
2365
2366/*
2367 * Variation on win32pipe.popen
2368 *
2369 * The result of this function is 2 pipes - the processes stdin,
2370 * and stdout+stderr combined as a single pipe.
2371 */
2372
2373static PyObject *
2374win32_popen4(PyObject *self, PyObject *args)
2375{
2376 PyObject *f;
2377 int tm = 0;
2378
2379 char *cmdstring;
2380 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002381 int bufsize = -1;
2382 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002383 return NULL;
2384
2385 if (*mode == 't')
2386 tm = _O_TEXT;
2387 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002388 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002389 return NULL;
2390 } else
2391 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002392
2393 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002394 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002395 return NULL;
2396 }
2397
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002398 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002399
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002400 return f;
2401}
2402
Mark Hammond08501372001-01-31 07:30:29 +00002403static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002404_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002405 HANDLE hStdin,
2406 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002407 HANDLE hStderr,
2408 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002409{
2410 PROCESS_INFORMATION piProcInfo;
2411 STARTUPINFO siStartInfo;
2412 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002413 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002414 int i;
2415 int x;
2416
2417 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002418 char *comshell;
2419
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002420 s1 = (char *)_alloca(i);
2421 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2422 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002423
2424 /* Explicitly check if we are using COMMAND.COM. If we are
2425 * then use the w9xpopen hack.
2426 */
2427 comshell = s1 + x;
2428 while (comshell >= s1 && *comshell != '\\')
2429 --comshell;
2430 ++comshell;
2431
2432 if (GetVersion() < 0x80000000 &&
2433 _stricmp(comshell, "command.com") != 0) {
2434 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002435 x = i + strlen(s3) + strlen(cmdstring) + 1;
2436 s2 = (char *)_alloca(x);
2437 ZeroMemory(s2, x);
2438 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2439 }
2440 else {
2441 /*
Tim Peters402d5982001-08-27 06:37:48 +00002442 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2443 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002444 */
Mark Hammond08501372001-01-31 07:30:29 +00002445 char modulepath[_MAX_PATH];
2446 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002447 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2448 for (i = x = 0; modulepath[i]; i++)
2449 if (modulepath[i] == '\\')
2450 x = i+1;
2451 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002452 /* Create the full-name to w9xpopen, so we can test it exists */
2453 strncat(modulepath,
2454 szConsoleSpawn,
2455 (sizeof(modulepath)/sizeof(modulepath[0]))
2456 -strlen(modulepath));
2457 if (stat(modulepath, &statinfo) != 0) {
2458 /* Eeek - file-not-found - possibly an embedding
2459 situation - see if we can locate it in sys.prefix
2460 */
2461 strncpy(modulepath,
2462 Py_GetExecPrefix(),
2463 sizeof(modulepath)/sizeof(modulepath[0]));
2464 if (modulepath[strlen(modulepath)-1] != '\\')
2465 strcat(modulepath, "\\");
2466 strncat(modulepath,
2467 szConsoleSpawn,
2468 (sizeof(modulepath)/sizeof(modulepath[0]))
2469 -strlen(modulepath));
2470 /* No where else to look - raise an easily identifiable
2471 error, rather than leaving Windows to report
2472 "file not found" - as the user is probably blissfully
2473 unaware this shim EXE is used, and it will confuse them.
2474 (well, it confused me for a while ;-)
2475 */
2476 if (stat(modulepath, &statinfo) != 0) {
2477 PyErr_Format(PyExc_RuntimeError,
2478 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002479 "for popen to work with your shell "
2480 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002481 szConsoleSpawn);
2482 return FALSE;
2483 }
2484 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002485 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2486 strlen(modulepath) +
2487 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002488
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002489 s2 = (char *)_alloca(x);
2490 ZeroMemory(s2, x);
2491 sprintf(
2492 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002493 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002494 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002495 s1,
2496 s3,
2497 cmdstring);
2498 }
2499 }
2500
2501 /* Could be an else here to try cmd.exe / command.com in the path
2502 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002503 else {
Tim Peters402d5982001-08-27 06:37:48 +00002504 PyErr_SetString(PyExc_RuntimeError,
2505 "Cannot locate a COMSPEC environment variable to "
2506 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002507 return FALSE;
2508 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002509
2510 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2511 siStartInfo.cb = sizeof(STARTUPINFO);
2512 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2513 siStartInfo.hStdInput = hStdin;
2514 siStartInfo.hStdOutput = hStdout;
2515 siStartInfo.hStdError = hStderr;
2516 siStartInfo.wShowWindow = SW_HIDE;
2517
2518 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002519 s2,
2520 NULL,
2521 NULL,
2522 TRUE,
2523 CREATE_NEW_CONSOLE,
2524 NULL,
2525 NULL,
2526 &siStartInfo,
2527 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002528 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002529 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002530
Mark Hammondb37a3732000-08-14 04:47:33 +00002531 /* Return process handle */
2532 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002533 return TRUE;
2534 }
Tim Peters402d5982001-08-27 06:37:48 +00002535 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002536 return FALSE;
2537}
2538
2539/* The following code is based off of KB: Q190351 */
2540
2541static PyObject *
2542_PyPopen(char *cmdstring, int mode, int n)
2543{
2544 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2545 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002546 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002547
2548 SECURITY_ATTRIBUTES saAttr;
2549 BOOL fSuccess;
2550 int fd1, fd2, fd3;
2551 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002552 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002553 PyObject *f;
2554
2555 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2556 saAttr.bInheritHandle = TRUE;
2557 saAttr.lpSecurityDescriptor = NULL;
2558
2559 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2560 return win32_error("CreatePipe", NULL);
2561
2562 /* Create new output read handle and the input write handle. Set
2563 * the inheritance properties to FALSE. Otherwise, the child inherits
2564 * the these handles; resulting in non-closeable handles to the pipes
2565 * being created. */
2566 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002567 GetCurrentProcess(), &hChildStdinWrDup, 0,
2568 FALSE,
2569 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002570 if (!fSuccess)
2571 return win32_error("DuplicateHandle", NULL);
2572
2573 /* Close the inheritable version of ChildStdin
2574 that we're using. */
2575 CloseHandle(hChildStdinWr);
2576
2577 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2578 return win32_error("CreatePipe", NULL);
2579
2580 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002581 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2582 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002583 if (!fSuccess)
2584 return win32_error("DuplicateHandle", NULL);
2585
2586 /* Close the inheritable version of ChildStdout
2587 that we're using. */
2588 CloseHandle(hChildStdoutRd);
2589
2590 if (n != POPEN_4) {
2591 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2592 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002593 fSuccess = DuplicateHandle(GetCurrentProcess(),
2594 hChildStderrRd,
2595 GetCurrentProcess(),
2596 &hChildStderrRdDup, 0,
2597 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002598 if (!fSuccess)
2599 return win32_error("DuplicateHandle", NULL);
2600 /* Close the inheritable version of ChildStdErr that we're using. */
2601 CloseHandle(hChildStderrRd);
2602 }
2603
2604 switch (n) {
2605 case POPEN_1:
2606 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2607 case _O_WRONLY | _O_TEXT:
2608 /* Case for writing to child Stdin in text mode. */
2609 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2610 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002611 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002612 PyFile_SetBufSize(f, 0);
2613 /* We don't care about these pipes anymore, so close them. */
2614 CloseHandle(hChildStdoutRdDup);
2615 CloseHandle(hChildStderrRdDup);
2616 break;
2617
2618 case _O_RDONLY | _O_TEXT:
2619 /* Case for reading from child Stdout in text mode. */
2620 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2621 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002622 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002623 PyFile_SetBufSize(f, 0);
2624 /* We don't care about these pipes anymore, so close them. */
2625 CloseHandle(hChildStdinWrDup);
2626 CloseHandle(hChildStderrRdDup);
2627 break;
2628
2629 case _O_RDONLY | _O_BINARY:
2630 /* Case for readinig from child Stdout in binary mode. */
2631 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2632 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002633 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002634 PyFile_SetBufSize(f, 0);
2635 /* We don't care about these pipes anymore, so close them. */
2636 CloseHandle(hChildStdinWrDup);
2637 CloseHandle(hChildStderrRdDup);
2638 break;
2639
2640 case _O_WRONLY | _O_BINARY:
2641 /* Case for writing to child Stdin in binary mode. */
2642 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2643 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002644 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002645 PyFile_SetBufSize(f, 0);
2646 /* We don't care about these pipes anymore, so close them. */
2647 CloseHandle(hChildStdoutRdDup);
2648 CloseHandle(hChildStderrRdDup);
2649 break;
2650 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002651 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002652 break;
2653
2654 case POPEN_2:
2655 case POPEN_4:
2656 {
2657 char *m1, *m2;
2658 PyObject *p1, *p2;
2659
2660 if (mode && _O_TEXT) {
2661 m1 = "r";
2662 m2 = "w";
2663 } else {
2664 m1 = "rb";
2665 m2 = "wb";
2666 }
2667
2668 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2669 f1 = _fdopen(fd1, m2);
2670 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2671 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002672 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002673 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002674 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002675 PyFile_SetBufSize(p2, 0);
2676
2677 if (n != 4)
2678 CloseHandle(hChildStderrRdDup);
2679
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002680 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002681 Py_XDECREF(p1);
2682 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002683 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002684 break;
2685 }
2686
2687 case POPEN_3:
2688 {
2689 char *m1, *m2;
2690 PyObject *p1, *p2, *p3;
2691
2692 if (mode && _O_TEXT) {
2693 m1 = "r";
2694 m2 = "w";
2695 } else {
2696 m1 = "rb";
2697 m2 = "wb";
2698 }
2699
2700 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2701 f1 = _fdopen(fd1, m2);
2702 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2703 f2 = _fdopen(fd2, m1);
2704 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2705 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002706 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002707 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2708 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002709 PyFile_SetBufSize(p1, 0);
2710 PyFile_SetBufSize(p2, 0);
2711 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002712 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002713 Py_XDECREF(p1);
2714 Py_XDECREF(p2);
2715 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002716 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002717 break;
2718 }
2719 }
2720
2721 if (n == POPEN_4) {
2722 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002723 hChildStdinRd,
2724 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002725 hChildStdoutWr,
2726 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002727 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002728 }
2729 else {
2730 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002731 hChildStdinRd,
2732 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002733 hChildStderrWr,
2734 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002735 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002736 }
2737
Mark Hammondb37a3732000-08-14 04:47:33 +00002738 /*
2739 * Insert the files we've created into the process dictionary
2740 * all referencing the list with the process handle and the
2741 * initial number of files (see description below in _PyPclose).
2742 * Since if _PyPclose later tried to wait on a process when all
2743 * handles weren't closed, it could create a deadlock with the
2744 * child, we spend some energy here to try to ensure that we
2745 * either insert all file handles into the dictionary or none
2746 * at all. It's a little clumsy with the various popen modes
2747 * and variable number of files involved.
2748 */
2749 if (!_PyPopenProcs) {
2750 _PyPopenProcs = PyDict_New();
2751 }
2752
2753 if (_PyPopenProcs) {
2754 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2755 int ins_rc[3];
2756
2757 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2758 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2759
2760 procObj = PyList_New(2);
2761 hProcessObj = PyLong_FromVoidPtr(hProcess);
2762 intObj = PyInt_FromLong(file_count);
2763
2764 if (procObj && hProcessObj && intObj) {
2765 PyList_SetItem(procObj,0,hProcessObj);
2766 PyList_SetItem(procObj,1,intObj);
2767
2768 fileObj[0] = PyLong_FromVoidPtr(f1);
2769 if (fileObj[0]) {
2770 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2771 fileObj[0],
2772 procObj);
2773 }
2774 if (file_count >= 2) {
2775 fileObj[1] = PyLong_FromVoidPtr(f2);
2776 if (fileObj[1]) {
2777 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2778 fileObj[1],
2779 procObj);
2780 }
2781 }
2782 if (file_count >= 3) {
2783 fileObj[2] = PyLong_FromVoidPtr(f3);
2784 if (fileObj[2]) {
2785 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2786 fileObj[2],
2787 procObj);
2788 }
2789 }
2790
2791 if (ins_rc[0] < 0 || !fileObj[0] ||
2792 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2793 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2794 /* Something failed - remove any dictionary
2795 * entries that did make it.
2796 */
2797 if (!ins_rc[0] && fileObj[0]) {
2798 PyDict_DelItem(_PyPopenProcs,
2799 fileObj[0]);
2800 }
2801 if (!ins_rc[1] && fileObj[1]) {
2802 PyDict_DelItem(_PyPopenProcs,
2803 fileObj[1]);
2804 }
2805 if (!ins_rc[2] && fileObj[2]) {
2806 PyDict_DelItem(_PyPopenProcs,
2807 fileObj[2]);
2808 }
2809 }
2810 }
2811
2812 /*
2813 * Clean up our localized references for the dictionary keys
2814 * and value since PyDict_SetItem will Py_INCREF any copies
2815 * that got placed in the dictionary.
2816 */
2817 Py_XDECREF(procObj);
2818 Py_XDECREF(fileObj[0]);
2819 Py_XDECREF(fileObj[1]);
2820 Py_XDECREF(fileObj[2]);
2821 }
2822
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002823 /* Child is launched. Close the parents copy of those pipe
2824 * handles that only the child should have open. You need to
2825 * make sure that no handles to the write end of the output pipe
2826 * are maintained in this process or else the pipe will not close
2827 * when the child process exits and the ReadFile will hang. */
2828
2829 if (!CloseHandle(hChildStdinRd))
2830 return win32_error("CloseHandle", NULL);
2831
2832 if (!CloseHandle(hChildStdoutWr))
2833 return win32_error("CloseHandle", NULL);
2834
2835 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2836 return win32_error("CloseHandle", NULL);
2837
2838 return f;
2839}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002840
2841/*
2842 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2843 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002844 *
2845 * This function uses the _PyPopenProcs dictionary in order to map the
2846 * input file pointer to information about the process that was
2847 * originally created by the popen* call that created the file pointer.
2848 * The dictionary uses the file pointer as a key (with one entry
2849 * inserted for each file returned by the original popen* call) and a
2850 * single list object as the value for all files from a single call.
2851 * The list object contains the Win32 process handle at [0], and a file
2852 * count at [1], which is initialized to the total number of file
2853 * handles using that list.
2854 *
2855 * This function closes whichever handle it is passed, and decrements
2856 * the file count in the dictionary for the process handle pointed to
2857 * by this file. On the last close (when the file count reaches zero),
2858 * this function will wait for the child process and then return its
2859 * exit code as the result of the close() operation. This permits the
2860 * files to be closed in any order - it is always the close() of the
2861 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002862 */
Tim Peters736aa322000-09-01 06:51:24 +00002863
2864 /* RED_FLAG 31-Aug-2000 Tim
2865 * This is always called (today!) between a pair of
2866 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2867 * macros. So the thread running this has no valid thread state, as
2868 * far as Python is concerned. However, this calls some Python API
2869 * functions that cannot be called safely without a valid thread
2870 * state, in particular PyDict_GetItem.
2871 * As a temporary hack (although it may last for years ...), we
2872 * *rely* on not having a valid thread state in this function, in
2873 * order to create our own "from scratch".
2874 * This will deadlock if _PyPclose is ever called by a thread
2875 * holding the global lock.
2876 */
2877
Fredrik Lundh56055a42000-07-23 19:47:12 +00002878static int _PyPclose(FILE *file)
2879{
Fredrik Lundh20318932000-07-26 17:29:12 +00002880 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002881 DWORD exit_code;
2882 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002883 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2884 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002885#ifdef WITH_THREAD
2886 PyInterpreterState* pInterpreterState;
2887 PyThreadState* pThreadState;
2888#endif
2889
Fredrik Lundh20318932000-07-26 17:29:12 +00002890 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002891 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002892 */
2893 result = fclose(file);
2894
Tim Peters736aa322000-09-01 06:51:24 +00002895#ifdef WITH_THREAD
2896 /* Bootstrap a valid thread state into existence. */
2897 pInterpreterState = PyInterpreterState_New();
2898 if (!pInterpreterState) {
2899 /* Well, we're hosed now! We don't have a thread
2900 * state, so can't call a nice error routine, or raise
2901 * an exception. Just die.
2902 */
2903 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002904 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002905 return -1; /* unreachable */
2906 }
2907 pThreadState = PyThreadState_New(pInterpreterState);
2908 if (!pThreadState) {
2909 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002910 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002911 return -1; /* unreachable */
2912 }
2913 /* Grab the global lock. Note that this will deadlock if the
2914 * current thread already has the lock! (see RED_FLAG comments
2915 * before this function)
2916 */
2917 PyEval_RestoreThread(pThreadState);
2918#endif
2919
Fredrik Lundh56055a42000-07-23 19:47:12 +00002920 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002921 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2922 (procObj = PyDict_GetItem(_PyPopenProcs,
2923 fileObj)) != NULL &&
2924 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2925 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2926
2927 hProcess = PyLong_AsVoidPtr(hProcessObj);
2928 file_count = PyInt_AsLong(intObj);
2929
2930 if (file_count > 1) {
2931 /* Still other files referencing process */
2932 file_count--;
2933 PyList_SetItem(procObj,1,
2934 PyInt_FromLong(file_count));
2935 } else {
2936 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002937 if (result != EOF &&
2938 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2939 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002940 /* Possible truncation here in 16-bit environments, but
2941 * real exit codes are just the lower byte in any event.
2942 */
2943 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002944 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002945 /* Indicate failure - this will cause the file object
2946 * to raise an I/O error and translate the last Win32
2947 * error code from errno. We do have a problem with
2948 * last errors that overlap the normal errno table,
2949 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002950 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002951 if (result != EOF) {
2952 /* If the error wasn't from the fclose(), then
2953 * set errno for the file object error handling.
2954 */
2955 errno = GetLastError();
2956 }
2957 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002958 }
2959
2960 /* Free up the native handle at this point */
2961 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002962 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002963
Mark Hammondb37a3732000-08-14 04:47:33 +00002964 /* Remove this file pointer from dictionary */
2965 PyDict_DelItem(_PyPopenProcs, fileObj);
2966
2967 if (PyDict_Size(_PyPopenProcs) == 0) {
2968 Py_DECREF(_PyPopenProcs);
2969 _PyPopenProcs = NULL;
2970 }
2971
2972 } /* if object retrieval ok */
2973
2974 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002975 } /* if _PyPopenProcs */
2976
Tim Peters736aa322000-09-01 06:51:24 +00002977#ifdef WITH_THREAD
2978 /* Tear down the thread & interpreter states.
2979 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002980 * call the thread clear & delete functions, and indeed insist on
2981 * doing that themselves. The lock must be held during the clear, but
2982 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002983 */
2984 PyInterpreterState_Clear(pInterpreterState);
2985 PyEval_ReleaseThread(pThreadState);
2986 PyInterpreterState_Delete(pInterpreterState);
2987#endif
2988
Fredrik Lundh56055a42000-07-23 19:47:12 +00002989 return result;
2990}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002991
2992#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002994posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002995{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002996 char *name;
2997 char *mode = "r";
2998 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002999 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003000 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003001 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003002 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003003 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003004 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003005 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003006 if (fp == NULL)
3007 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003008 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003009 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003010 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003011 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003012}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003013#endif
3014
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003015#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003017
Guido van Rossumb6775db1994-08-01 11:34:53 +00003018#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003019static char posix_setuid__doc__[] =
3020"setuid(uid) -> None\n\
3021Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003023posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003024{
3025 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003026 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003027 return NULL;
3028 if (setuid(uid) < 0)
3029 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003030 Py_INCREF(Py_None);
3031 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003032}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003033#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003034
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003035
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003036#ifdef HAVE_SETEUID
3037static char posix_seteuid__doc__[] =
3038"seteuid(uid) -> None\n\
3039Set the current process's effective user id.";
3040static PyObject *
3041posix_seteuid (PyObject *self, PyObject *args)
3042{
3043 int euid;
3044 if (!PyArg_ParseTuple(args, "i", &euid)) {
3045 return NULL;
3046 } else if (seteuid(euid) < 0) {
3047 return posix_error();
3048 } else {
3049 Py_INCREF(Py_None);
3050 return Py_None;
3051 }
3052}
3053#endif /* HAVE_SETEUID */
3054
3055#ifdef HAVE_SETEGID
3056static char posix_setegid__doc__[] =
3057"setegid(gid) -> None\n\
3058Set the current process's effective group id.";
3059static PyObject *
3060posix_setegid (PyObject *self, PyObject *args)
3061{
3062 int egid;
3063 if (!PyArg_ParseTuple(args, "i", &egid)) {
3064 return NULL;
3065 } else if (setegid(egid) < 0) {
3066 return posix_error();
3067 } else {
3068 Py_INCREF(Py_None);
3069 return Py_None;
3070 }
3071}
3072#endif /* HAVE_SETEGID */
3073
3074#ifdef HAVE_SETREUID
3075static char posix_setreuid__doc__[] =
3076"seteuid(ruid, euid) -> None\n\
3077Set the current process's real and effective user ids.";
3078static PyObject *
3079posix_setreuid (PyObject *self, PyObject *args)
3080{
3081 int ruid, euid;
3082 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3083 return NULL;
3084 } else if (setreuid(ruid, euid) < 0) {
3085 return posix_error();
3086 } else {
3087 Py_INCREF(Py_None);
3088 return Py_None;
3089 }
3090}
3091#endif /* HAVE_SETREUID */
3092
3093#ifdef HAVE_SETREGID
3094static char posix_setregid__doc__[] =
3095"setegid(rgid, egid) -> None\n\
3096Set the current process's real and effective group ids.";
3097static PyObject *
3098posix_setregid (PyObject *self, PyObject *args)
3099{
3100 int rgid, egid;
3101 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3102 return NULL;
3103 } else if (setregid(rgid, egid) < 0) {
3104 return posix_error();
3105 } else {
3106 Py_INCREF(Py_None);
3107 return Py_None;
3108 }
3109}
3110#endif /* HAVE_SETREGID */
3111
Guido van Rossumb6775db1994-08-01 11:34:53 +00003112#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003113static char posix_setgid__doc__[] =
3114"setgid(gid) -> None\n\
3115Set the current process's group id.";
3116
Barry Warsaw53699e91996-12-10 23:23:01 +00003117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003118posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003119{
3120 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003121 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003122 return NULL;
3123 if (setgid(gid) < 0)
3124 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003125 Py_INCREF(Py_None);
3126 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003127}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003128#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003129
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003130#ifdef HAVE_SETGROUPS
3131static char posix_setgroups__doc__[] =
3132"setgroups(list) -> None\n\
3133Set the groups of the current process to list.";
3134
3135static PyObject *
3136posix_setgroups(PyObject *self, PyObject *args)
3137{
3138 PyObject *groups;
3139 int i, len;
3140 gid_t grouplist[MAX_GROUPS];
3141
3142 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3143 return NULL;
3144 if (!PySequence_Check(groups)) {
3145 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3146 return NULL;
3147 }
3148 len = PySequence_Size(groups);
3149 if (len > MAX_GROUPS) {
3150 PyErr_SetString(PyExc_ValueError, "too many groups");
3151 return NULL;
3152 }
3153 for(i = 0; i < len; i++) {
3154 PyObject *elem;
3155 elem = PySequence_GetItem(groups, i);
3156 if (!elem)
3157 return NULL;
3158 if (!PyInt_Check(elem)) {
3159 PyErr_SetString(PyExc_TypeError,
3160 "groups must be integers");
3161 Py_DECREF(elem);
3162 return NULL;
3163 }
3164 /* XXX: check that value fits into gid_t. */
3165 grouplist[i] = PyInt_AsLong(elem);
3166 Py_DECREF(elem);
3167 }
3168
3169 if (setgroups(len, grouplist) < 0)
3170 return posix_error();
3171 Py_INCREF(Py_None);
3172 return Py_None;
3173}
3174#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Guido van Rossumb6775db1994-08-01 11:34:53 +00003176#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003177static char posix_waitpid__doc__[] =
3178"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003179Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003180
Barry Warsaw53699e91996-12-10 23:23:01 +00003181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003182posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003183{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003184 int pid, options;
3185#ifdef UNION_WAIT
3186 union wait status;
3187#define status_i (status.w_status)
3188#else
3189 int status;
3190#define status_i status
3191#endif
3192 status_i = 0;
3193
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003194 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003195 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003196 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003197#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003198 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003199#else
3200 pid = waitpid(pid, &status, options);
3201#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003202 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003203 if (pid == -1)
3204 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003205 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003206 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003207}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003208#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003210
Guido van Rossumad0ee831995-03-01 10:34:45 +00003211#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003212static char posix_wait__doc__[] =
3213"wait() -> (pid, status)\n\
3214Wait for completion of a child process.";
3215
Barry Warsaw53699e91996-12-10 23:23:01 +00003216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003217posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003218{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003219 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003220#ifdef UNION_WAIT
3221 union wait status;
3222#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003223#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003224 int status;
3225#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003226#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003227 if (!PyArg_ParseTuple(args, ":wait"))
3228 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003229 status_i = 0;
3230 Py_BEGIN_ALLOW_THREADS
3231 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003232 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003233 if (pid == -1)
3234 return posix_error();
3235 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003236 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003237#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003238}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003239#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003241
3242static char posix_lstat__doc__[] =
3243"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3244Like stat(path), but do not follow symbolic links.";
3245
Barry Warsaw53699e91996-12-10 23:23:01 +00003246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003247posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003248{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003249#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003250 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003251#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003252 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003253#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003254}
3255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003256
Guido van Rossumb6775db1994-08-01 11:34:53 +00003257#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003258static char posix_readlink__doc__[] =
3259"readlink(path) -> path\n\
3260Return a string representing the path to which the symbolic link points.";
3261
Barry Warsaw53699e91996-12-10 23:23:01 +00003262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003263posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003264{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003265 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003266 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003267 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003268 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003269 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003270 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003271 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003272 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003273 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003274 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003275 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003276}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003277#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003279
Guido van Rossumb6775db1994-08-01 11:34:53 +00003280#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003281static char posix_symlink__doc__[] =
3282"symlink(src, dst) -> None\n\
3283Create a symbolic link.";
3284
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003286posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003287{
Mark Hammondef8b6542001-05-13 08:04:26 +00003288 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003289}
3290#endif /* HAVE_SYMLINK */
3291
3292
3293#ifdef HAVE_TIMES
3294#ifndef HZ
3295#define HZ 60 /* Universal constant :-) */
3296#endif /* HZ */
3297
Guido van Rossumd48f2521997-12-05 22:19:34 +00003298#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3299static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003300system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003301{
3302 ULONG value = 0;
3303
3304 Py_BEGIN_ALLOW_THREADS
3305 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3306 Py_END_ALLOW_THREADS
3307
3308 return value;
3309}
3310
3311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003312posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003313{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003314 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003315 return NULL;
3316
3317 /* Currently Only Uptime is Provided -- Others Later */
3318 return Py_BuildValue("ddddd",
3319 (double)0 /* t.tms_utime / HZ */,
3320 (double)0 /* t.tms_stime / HZ */,
3321 (double)0 /* t.tms_cutime / HZ */,
3322 (double)0 /* t.tms_cstime / HZ */,
3323 (double)system_uptime() / 1000);
3324}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003325#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003326static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003327posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003328{
3329 struct tms t;
3330 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003331 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003332 return NULL;
3333 errno = 0;
3334 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003335 if (c == (clock_t) -1)
3336 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003337 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003338 (double)t.tms_utime / HZ,
3339 (double)t.tms_stime / HZ,
3340 (double)t.tms_cutime / HZ,
3341 (double)t.tms_cstime / HZ,
3342 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003343}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003344#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003345#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003346
3347
Guido van Rossum87755a21996-09-07 00:59:43 +00003348#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003349#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003350static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003351posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003352{
3353 FILETIME create, exit, kernel, user;
3354 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003355 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003356 return NULL;
3357 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003358 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3359 /* The fields of a FILETIME structure are the hi and lo part
3360 of a 64-bit value expressed in 100 nanosecond units.
3361 1e7 is one second in such units; 1e-7 the inverse.
3362 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3363 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003364 return Py_BuildValue(
3365 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003366 (double)(kernel.dwHighDateTime*429.4967296 +
3367 kernel.dwLowDateTime*1e-7),
3368 (double)(user.dwHighDateTime*429.4967296 +
3369 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003370 (double)0,
3371 (double)0,
3372 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003373}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003374#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003375
3376#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003377static char posix_times__doc__[] =
3378"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3379Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003380#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003382
Guido van Rossumb6775db1994-08-01 11:34:53 +00003383#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003384static char posix_setsid__doc__[] =
3385"setsid() -> None\n\
3386Call the system call setsid().";
3387
Barry Warsaw53699e91996-12-10 23:23:01 +00003388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003389posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003390{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003391 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003392 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003393 if (setsid() < 0)
3394 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003395 Py_INCREF(Py_None);
3396 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003397}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003398#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003399
Guido van Rossumb6775db1994-08-01 11:34:53 +00003400#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003401static char posix_setpgid__doc__[] =
3402"setpgid(pid, pgrp) -> None\n\
3403Call the system call setpgid().";
3404
Barry Warsaw53699e91996-12-10 23:23:01 +00003405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003406posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003407{
3408 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003409 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003410 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003411 if (setpgid(pid, pgrp) < 0)
3412 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003413 Py_INCREF(Py_None);
3414 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003415}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003416#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003418
Guido van Rossumb6775db1994-08-01 11:34:53 +00003419#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003420static char posix_tcgetpgrp__doc__[] =
3421"tcgetpgrp(fd) -> pgid\n\
3422Return the process group associated with the terminal given by a fd.";
3423
Barry Warsaw53699e91996-12-10 23:23:01 +00003424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003425posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003426{
3427 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003428 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003429 return NULL;
3430 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003431 if (pgid < 0)
3432 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003433 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003434}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003435#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003436
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003437
Guido van Rossumb6775db1994-08-01 11:34:53 +00003438#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003439static char posix_tcsetpgrp__doc__[] =
3440"tcsetpgrp(fd, pgid) -> None\n\
3441Set the process group associated with the terminal given by a fd.";
3442
Barry Warsaw53699e91996-12-10 23:23:01 +00003443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003444posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003445{
3446 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003447 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003448 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003449 if (tcsetpgrp(fd, pgid) < 0)
3450 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003451 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003452 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003453}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003454#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003455
Guido van Rossum687dd131993-05-17 08:34:16 +00003456/* Functions acting on file descriptors */
3457
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003458static char posix_open__doc__[] =
3459"open(filename, flag [, mode=0777]) -> fd\n\
3460Open a file (for low level IO).";
3461
Barry Warsaw53699e91996-12-10 23:23:01 +00003462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003463posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003464{
Mark Hammondef8b6542001-05-13 08:04:26 +00003465 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003466 int flag;
3467 int mode = 0777;
3468 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003469 if (!PyArg_ParseTuple(args, "eti|i",
3470 Py_FileSystemDefaultEncoding, &file,
3471 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003472 return NULL;
3473
Barry Warsaw53699e91996-12-10 23:23:01 +00003474 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003475 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003476 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003477 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003478 return posix_error_with_allocated_filename(file);
3479 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003480 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003481}
3482
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003483
3484static char posix_close__doc__[] =
3485"close(fd) -> None\n\
3486Close a file descriptor (for low level IO).";
3487
Barry Warsaw53699e91996-12-10 23:23:01 +00003488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003489posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003490{
3491 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003492 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003493 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003494 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003495 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003496 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003497 if (res < 0)
3498 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003499 Py_INCREF(Py_None);
3500 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003501}
3502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003503
3504static char posix_dup__doc__[] =
3505"dup(fd) -> fd2\n\
3506Return a duplicate of a file descriptor.";
3507
Barry Warsaw53699e91996-12-10 23:23:01 +00003508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003509posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003510{
3511 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003512 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003513 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003514 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003515 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003516 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003517 if (fd < 0)
3518 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003519 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003520}
3521
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003522
3523static char posix_dup2__doc__[] =
3524"dup2(fd, fd2) -> None\n\
3525Duplicate file descriptor.";
3526
Barry Warsaw53699e91996-12-10 23:23:01 +00003527static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003528posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003529{
3530 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003531 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003532 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003533 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003534 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003535 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003536 if (res < 0)
3537 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003538 Py_INCREF(Py_None);
3539 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003540}
3541
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003542
3543static char posix_lseek__doc__[] =
3544"lseek(fd, pos, how) -> newpos\n\
3545Set the current position of a file descriptor.";
3546
Barry Warsaw53699e91996-12-10 23:23:01 +00003547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003548posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003549{
3550 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003551#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003552 LONG_LONG pos, res;
3553#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003554 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003555#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003556 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003557 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003558 return NULL;
3559#ifdef SEEK_SET
3560 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3561 switch (how) {
3562 case 0: how = SEEK_SET; break;
3563 case 1: how = SEEK_CUR; break;
3564 case 2: how = SEEK_END; break;
3565 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003566#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003567
3568#if !defined(HAVE_LARGEFILE_SUPPORT)
3569 pos = PyInt_AsLong(posobj);
3570#else
3571 pos = PyLong_Check(posobj) ?
3572 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3573#endif
3574 if (PyErr_Occurred())
3575 return NULL;
3576
Barry Warsaw53699e91996-12-10 23:23:01 +00003577 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003578#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003579 res = _lseeki64(fd, pos, how);
3580#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003581 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003582#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003583 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003584 if (res < 0)
3585 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003586
3587#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003588 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003589#else
3590 return PyLong_FromLongLong(res);
3591#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003592}
3593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003594
3595static char posix_read__doc__[] =
3596"read(fd, buffersize) -> string\n\
3597Read a file descriptor.";
3598
Barry Warsaw53699e91996-12-10 23:23:01 +00003599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003600posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003601{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003602 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003603 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003604 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003605 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003606 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003607 if (buffer == NULL)
3608 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003609 Py_BEGIN_ALLOW_THREADS
3610 n = read(fd, PyString_AsString(buffer), size);
3611 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003612 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003613 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003614 return posix_error();
3615 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003616 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003617 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003618 return buffer;
3619}
3620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003621
3622static char posix_write__doc__[] =
3623"write(fd, string) -> byteswritten\n\
3624Write a string to a file descriptor.";
3625
Barry Warsaw53699e91996-12-10 23:23:01 +00003626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003627posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003628{
3629 int fd, size;
3630 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003631 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003632 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003633 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003634 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003635 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003636 if (size < 0)
3637 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003638 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003639}
3640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003641
3642static char posix_fstat__doc__[]=
3643"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3644Like stat(), but for an open file descriptor.";
3645
Barry Warsaw53699e91996-12-10 23:23:01 +00003646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003647posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003648{
3649 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003650 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003651 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003652 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003653 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003654 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003655 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003656 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003657 if (res != 0)
3658 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003659
3660 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003661}
3662
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003663
3664static char posix_fdopen__doc__[] =
3665"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3666Return an open file object connected to a file descriptor.";
3667
Barry Warsaw53699e91996-12-10 23:23:01 +00003668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003669posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003670{
Guido van Rossum687dd131993-05-17 08:34:16 +00003671 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003672 char *mode = "r";
3673 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003674 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003675 PyObject *f;
3676 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003677 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003678
Barry Warsaw53699e91996-12-10 23:23:01 +00003679 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003680 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003681 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003682 if (fp == NULL)
3683 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003684 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003685 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003686 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003687 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003688}
3689
Skip Montanaro1517d842000-07-19 14:34:14 +00003690static char posix_isatty__doc__[] =
3691"isatty(fd) -> Boolean\n\
3692Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003693connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003694
3695static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003696posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003697{
3698 int fd;
3699 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3700 return NULL;
3701 return Py_BuildValue("i", isatty(fd));
3702}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003703
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003704#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003705static char posix_pipe__doc__[] =
3706"pipe() -> (read_end, write_end)\n\
3707Create a pipe.";
3708
Barry Warsaw53699e91996-12-10 23:23:01 +00003709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003710posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003711{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003712#if defined(PYOS_OS2)
3713 HFILE read, write;
3714 APIRET rc;
3715
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003716 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003717 return NULL;
3718
3719 Py_BEGIN_ALLOW_THREADS
3720 rc = DosCreatePipe( &read, &write, 4096);
3721 Py_END_ALLOW_THREADS
3722 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003723 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003724
3725 return Py_BuildValue("(ii)", read, write);
3726#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003727#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003728 int fds[2];
3729 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003730 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003731 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003732 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003733 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003734 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003735 if (res != 0)
3736 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003737 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003738#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003739 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003740 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003741 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003742 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003743 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003744 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003745 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003746 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003747 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003748 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003749 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3750 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003751 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003752#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003753#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003754}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003755#endif /* HAVE_PIPE */
3756
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003757
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003758#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003759static char posix_mkfifo__doc__[] =
3760"mkfifo(file, [, mode=0666]) -> None\n\
3761Create a FIFO (a POSIX named pipe).";
3762
Barry Warsaw53699e91996-12-10 23:23:01 +00003763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003764posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003765{
3766 char *file;
3767 int mode = 0666;
3768 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003769 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003770 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003771 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003772 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003773 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003774 if (res < 0)
3775 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003776 Py_INCREF(Py_None);
3777 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003778}
3779#endif
3780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003781
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003782#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003783static char posix_ftruncate__doc__[] =
3784"ftruncate(fd, length) -> None\n\
3785Truncate a file to a specified length.";
3786
Barry Warsaw53699e91996-12-10 23:23:01 +00003787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003788posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003789{
3790 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003791 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003792 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003793 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003794
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003795 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003796 return NULL;
3797
3798#if !defined(HAVE_LARGEFILE_SUPPORT)
3799 length = PyInt_AsLong(lenobj);
3800#else
3801 length = PyLong_Check(lenobj) ?
3802 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3803#endif
3804 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003805 return NULL;
3806
Barry Warsaw53699e91996-12-10 23:23:01 +00003807 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003808 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003809 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003810 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003811 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003812 return NULL;
3813 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003814 Py_INCREF(Py_None);
3815 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003816}
3817#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003818
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003819#ifdef NeXT
3820#define HAVE_PUTENV
3821/* Steve Spicklemire got this putenv from NeXTAnswers */
3822static int
3823putenv(char *newval)
3824{
3825 extern char **environ;
3826
3827 static int firstTime = 1;
3828 char **ep;
3829 char *cp;
3830 int esiz;
3831 char *np;
3832
3833 if (!(np = strchr(newval, '=')))
3834 return 1;
3835 *np = '\0';
3836
3837 /* look it up */
3838 for (ep=environ ; *ep ; ep++)
3839 {
3840 /* this should always be true... */
3841 if (cp = strchr(*ep, '='))
3842 {
3843 *cp = '\0';
3844 if (!strcmp(*ep, newval))
3845 {
3846 /* got it! */
3847 *cp = '=';
3848 break;
3849 }
3850 *cp = '=';
3851 }
3852 else
3853 {
3854 *np = '=';
3855 return 1;
3856 }
3857 }
3858
3859 *np = '=';
3860 if (*ep)
3861 {
3862 /* the string was already there:
3863 just replace it with the new one */
3864 *ep = newval;
3865 return 0;
3866 }
3867
3868 /* expand environ by one */
3869 for (esiz=2, ep=environ ; *ep ; ep++)
3870 esiz++;
3871 if (firstTime)
3872 {
3873 char **epp;
3874 char **newenv;
3875 if (!(newenv = malloc(esiz * sizeof(char *))))
3876 return 1;
3877
3878 for (ep=environ, epp=newenv ; *ep ;)
3879 *epp++ = *ep++;
3880 *epp++ = newval;
3881 *epp = (char *) 0;
3882 environ = newenv;
3883 }
3884 else
3885 {
3886 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3887 return 1;
3888 environ[esiz - 2] = newval;
3889 environ[esiz - 1] = (char *) 0;
3890 firstTime = 0;
3891 }
3892
3893 return 0;
3894}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003895#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003896
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003897
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003898#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003899static char posix_putenv__doc__[] =
3900"putenv(key, value) -> None\n\
3901Change or add an environment variable.";
3902
Fred Drake762e2061999-08-26 17:23:54 +00003903/* Save putenv() parameters as values here, so we can collect them when they
3904 * get re-set with another call for the same key. */
3905static PyObject *posix_putenv_garbage;
3906
Barry Warsaw53699e91996-12-10 23:23:01 +00003907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003908posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003909{
3910 char *s1, *s2;
3911 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003912 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003913
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003914 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003915 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003916
3917#if defined(PYOS_OS2)
3918 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3919 APIRET rc;
3920
3921 if (strlen(s2) == 0) /* If New Value is an Empty String */
3922 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3923
3924 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3925 if (rc != NO_ERROR)
3926 return os2_error(rc);
3927
3928 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3929 APIRET rc;
3930
3931 if (strlen(s2) == 0) /* If New Value is an Empty String */
3932 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3933
3934 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3935 if (rc != NO_ERROR)
3936 return os2_error(rc);
3937 } else {
3938#endif
3939
Fred Drake762e2061999-08-26 17:23:54 +00003940 /* XXX This can leak memory -- not easy to fix :-( */
3941 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3942 if (newstr == NULL)
3943 return PyErr_NoMemory();
3944 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003945 (void) sprintf(new, "%s=%s", s1, s2);
3946 if (putenv(new)) {
3947 posix_error();
3948 return NULL;
3949 }
Fred Drake762e2061999-08-26 17:23:54 +00003950 /* Install the first arg and newstr in posix_putenv_garbage;
3951 * this will cause previous value to be collected. This has to
3952 * happen after the real putenv() call because the old value
3953 * was still accessible until then. */
3954 if (PyDict_SetItem(posix_putenv_garbage,
3955 PyTuple_GET_ITEM(args, 0), newstr)) {
3956 /* really not much we can do; just leak */
3957 PyErr_Clear();
3958 }
3959 else {
3960 Py_DECREF(newstr);
3961 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003962
3963#if defined(PYOS_OS2)
3964 }
3965#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003966 Py_INCREF(Py_None);
3967 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003968}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003969#endif /* putenv */
3970
3971#ifdef HAVE_STRERROR
3972static char posix_strerror__doc__[] =
3973"strerror(code) -> string\n\
3974Translate an error code to a message string.";
3975
Guido van Rossumf68d8e52001-04-14 17:55:09 +00003976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003977posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003978{
3979 int code;
3980 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003981 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003982 return NULL;
3983 message = strerror(code);
3984 if (message == NULL) {
3985 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003986 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003987 return NULL;
3988 }
3989 return PyString_FromString(message);
3990}
3991#endif /* strerror */
3992
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003993
Guido van Rossumc9641791998-08-04 15:26:23 +00003994#ifdef HAVE_SYS_WAIT_H
3995
3996#ifdef WIFSTOPPED
3997static char posix_WIFSTOPPED__doc__[] =
3998"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003999Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004000
4001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004002posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004003{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004004#ifdef UNION_WAIT
4005 union wait status;
4006#define status_i (status.w_status)
4007#else
4008 int status;
4009#define status_i status
4010#endif
4011 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004012
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004013 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004014 {
4015 return NULL;
4016 }
4017
4018 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004019#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004020}
4021#endif /* WIFSTOPPED */
4022
4023#ifdef WIFSIGNALED
4024static char posix_WIFSIGNALED__doc__[] =
4025"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004026Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004027
4028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004029posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004030{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004031#ifdef UNION_WAIT
4032 union wait status;
4033#define status_i (status.w_status)
4034#else
4035 int status;
4036#define status_i status
4037#endif
4038 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004039
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004040 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004041 {
4042 return NULL;
4043 }
4044
4045 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004046#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004047}
4048#endif /* WIFSIGNALED */
4049
4050#ifdef WIFEXITED
4051static char posix_WIFEXITED__doc__[] =
4052"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004053Return true if the process returning 'status' exited using the exit()\n\
4054system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004055
4056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004057posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004058{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004059#ifdef UNION_WAIT
4060 union wait status;
4061#define status_i (status.w_status)
4062#else
4063 int status;
4064#define status_i status
4065#endif
4066 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004067
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004068 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004069 {
4070 return NULL;
4071 }
4072
4073 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004074#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004075}
4076#endif /* WIFEXITED */
4077
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004078#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004079static char posix_WEXITSTATUS__doc__[] =
4080"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004081Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004082
4083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004084posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004085{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004086#ifdef UNION_WAIT
4087 union wait status;
4088#define status_i (status.w_status)
4089#else
4090 int status;
4091#define status_i status
4092#endif
4093 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004094
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004095 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004096 {
4097 return NULL;
4098 }
4099
4100 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004101#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004102}
4103#endif /* WEXITSTATUS */
4104
4105#ifdef WTERMSIG
4106static char posix_WTERMSIG__doc__[] =
4107"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004108Return the signal that terminated the process that provided the 'status'\n\
4109value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004110
4111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004112posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004113{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004114#ifdef UNION_WAIT
4115 union wait status;
4116#define status_i (status.w_status)
4117#else
4118 int status;
4119#define status_i status
4120#endif
4121 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004122
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004123 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004124 {
4125 return NULL;
4126 }
4127
4128 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004129#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004130}
4131#endif /* WTERMSIG */
4132
4133#ifdef WSTOPSIG
4134static char posix_WSTOPSIG__doc__[] =
4135"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004136Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004137
4138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004139posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004140{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004141#ifdef UNION_WAIT
4142 union wait status;
4143#define status_i (status.w_status)
4144#else
4145 int status;
4146#define status_i status
4147#endif
4148 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004149
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004150 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004151 {
4152 return NULL;
4153 }
4154
4155 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004156#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004157}
4158#endif /* WSTOPSIG */
4159
4160#endif /* HAVE_SYS_WAIT_H */
4161
4162
Guido van Rossum94f6f721999-01-06 18:42:14 +00004163#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004164#ifdef _SCO_DS
4165/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4166 needed definitions in sys/statvfs.h */
4167#define _SVID3
4168#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004169#include <sys/statvfs.h>
4170
4171static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004172"fstatvfs(fd) -> \n\
4173 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004174Perform an fstatvfs system call on the given fd.";
4175
4176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004177posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004178{
4179 int fd, res;
4180 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004181 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004182 return NULL;
4183 Py_BEGIN_ALLOW_THREADS
4184 res = fstatvfs(fd, &st);
4185 Py_END_ALLOW_THREADS
4186 if (res != 0)
4187 return posix_error();
4188#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004189 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004190 (long) st.f_bsize,
4191 (long) st.f_frsize,
4192 (long) st.f_blocks,
4193 (long) st.f_bfree,
4194 (long) st.f_bavail,
4195 (long) st.f_files,
4196 (long) st.f_ffree,
4197 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004198 (long) st.f_flag,
4199 (long) st.f_namemax);
4200#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004201 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004202 (long) st.f_bsize,
4203 (long) st.f_frsize,
4204 (LONG_LONG) st.f_blocks,
4205 (LONG_LONG) st.f_bfree,
4206 (LONG_LONG) st.f_bavail,
4207 (LONG_LONG) st.f_files,
4208 (LONG_LONG) st.f_ffree,
4209 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004210 (long) st.f_flag,
4211 (long) st.f_namemax);
4212#endif
4213}
4214#endif /* HAVE_FSTATVFS */
4215
4216
4217#if defined(HAVE_STATVFS)
4218#include <sys/statvfs.h>
4219
4220static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004221"statvfs(path) -> \n\
4222 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004223Perform a statvfs system call on the given path.";
4224
4225static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004226posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004227{
4228 char *path;
4229 int res;
4230 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004231 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004232 return NULL;
4233 Py_BEGIN_ALLOW_THREADS
4234 res = statvfs(path, &st);
4235 Py_END_ALLOW_THREADS
4236 if (res != 0)
4237 return posix_error_with_filename(path);
4238#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004239 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004240 (long) st.f_bsize,
4241 (long) st.f_frsize,
4242 (long) st.f_blocks,
4243 (long) st.f_bfree,
4244 (long) st.f_bavail,
4245 (long) st.f_files,
4246 (long) st.f_ffree,
4247 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004248 (long) st.f_flag,
4249 (long) st.f_namemax);
4250#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004251 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004252 (long) st.f_bsize,
4253 (long) st.f_frsize,
4254 (LONG_LONG) st.f_blocks,
4255 (LONG_LONG) st.f_bfree,
4256 (LONG_LONG) st.f_bavail,
4257 (LONG_LONG) st.f_files,
4258 (LONG_LONG) st.f_ffree,
4259 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004260 (long) st.f_flag,
4261 (long) st.f_namemax);
4262#endif
4263}
4264#endif /* HAVE_STATVFS */
4265
4266
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004267#ifdef HAVE_TEMPNAM
4268static char posix_tempnam__doc__[] = "\
4269tempnam([dir[, prefix]]) -> string\n\
4270Return a unique name for a temporary file.\n\
4271The directory and a short may be specified as strings; they may be omitted\n\
4272or None if not needed.";
4273
4274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004275posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004276{
4277 PyObject *result = NULL;
4278 char *dir = NULL;
4279 char *pfx = NULL;
4280 char *name;
4281
4282 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4283 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004284
4285 if (PyErr_Warn(PyExc_RuntimeWarning,
4286 "tempnam is a potential security risk to your program") < 0)
4287 return NULL;
4288
Fred Drake78b71c22001-07-17 20:37:36 +00004289#ifdef MS_WIN32
4290 name = _tempnam(dir, pfx);
4291#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004292 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004293#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004294 if (name == NULL)
4295 return PyErr_NoMemory();
4296 result = PyString_FromString(name);
4297 free(name);
4298 return result;
4299}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004300#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004301
4302
4303#ifdef HAVE_TMPFILE
4304static char posix_tmpfile__doc__[] = "\
4305tmpfile() -> file object\n\
4306Create a temporary file with no directory entries.";
4307
4308static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004309posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004310{
4311 FILE *fp;
4312
4313 if (!PyArg_ParseTuple(args, ":tmpfile"))
4314 return NULL;
4315 fp = tmpfile();
4316 if (fp == NULL)
4317 return posix_error();
4318 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4319}
4320#endif
4321
4322
4323#ifdef HAVE_TMPNAM
4324static char posix_tmpnam__doc__[] = "\
4325tmpnam() -> string\n\
4326Return a unique name for a temporary file.";
4327
4328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004329posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004330{
4331 char buffer[L_tmpnam];
4332 char *name;
4333
4334 if (!PyArg_ParseTuple(args, ":tmpnam"))
4335 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004336
4337 if (PyErr_Warn(PyExc_RuntimeWarning,
4338 "tmpnam is a potential security risk to your program") < 0)
4339 return NULL;
4340
Greg Wardb48bc172000-03-01 21:51:56 +00004341#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004342 name = tmpnam_r(buffer);
4343#else
4344 name = tmpnam(buffer);
4345#endif
4346 if (name == NULL) {
4347 PyErr_SetObject(PyExc_OSError,
4348 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004349#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004350 "unexpected NULL from tmpnam_r"
4351#else
4352 "unexpected NULL from tmpnam"
4353#endif
4354 ));
4355 return NULL;
4356 }
4357 return PyString_FromString(buffer);
4358}
4359#endif
4360
4361
Fred Drakec9680921999-12-13 16:37:25 +00004362/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4363 * It maps strings representing configuration variable names to
4364 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004365 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004366 * rarely-used constants. There are three separate tables that use
4367 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004368 *
4369 * This code is always included, even if none of the interfaces that
4370 * need it are included. The #if hackery needed to avoid it would be
4371 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004372 */
4373struct constdef {
4374 char *name;
4375 long value;
4376};
4377
Fred Drake12c6e2d1999-12-14 21:25:03 +00004378static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004379conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4380 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004381{
4382 if (PyInt_Check(arg)) {
4383 *valuep = PyInt_AS_LONG(arg);
4384 return 1;
4385 }
4386 if (PyString_Check(arg)) {
4387 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004388 size_t lo = 0;
4389 size_t mid;
4390 size_t hi = tablesize;
4391 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004392 char *confname = PyString_AS_STRING(arg);
4393 while (lo < hi) {
4394 mid = (lo + hi) / 2;
4395 cmp = strcmp(confname, table[mid].name);
4396 if (cmp < 0)
4397 hi = mid;
4398 else if (cmp > 0)
4399 lo = mid + 1;
4400 else {
4401 *valuep = table[mid].value;
4402 return 1;
4403 }
4404 }
4405 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4406 }
4407 else
4408 PyErr_SetString(PyExc_TypeError,
4409 "configuration names must be strings or integers");
4410 return 0;
4411}
4412
4413
4414#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4415static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004416#ifdef _PC_ABI_AIO_XFER_MAX
4417 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4418#endif
4419#ifdef _PC_ABI_ASYNC_IO
4420 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4421#endif
Fred Drakec9680921999-12-13 16:37:25 +00004422#ifdef _PC_ASYNC_IO
4423 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4424#endif
4425#ifdef _PC_CHOWN_RESTRICTED
4426 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4427#endif
4428#ifdef _PC_FILESIZEBITS
4429 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4430#endif
4431#ifdef _PC_LAST
4432 {"PC_LAST", _PC_LAST},
4433#endif
4434#ifdef _PC_LINK_MAX
4435 {"PC_LINK_MAX", _PC_LINK_MAX},
4436#endif
4437#ifdef _PC_MAX_CANON
4438 {"PC_MAX_CANON", _PC_MAX_CANON},
4439#endif
4440#ifdef _PC_MAX_INPUT
4441 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4442#endif
4443#ifdef _PC_NAME_MAX
4444 {"PC_NAME_MAX", _PC_NAME_MAX},
4445#endif
4446#ifdef _PC_NO_TRUNC
4447 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4448#endif
4449#ifdef _PC_PATH_MAX
4450 {"PC_PATH_MAX", _PC_PATH_MAX},
4451#endif
4452#ifdef _PC_PIPE_BUF
4453 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4454#endif
4455#ifdef _PC_PRIO_IO
4456 {"PC_PRIO_IO", _PC_PRIO_IO},
4457#endif
4458#ifdef _PC_SOCK_MAXBUF
4459 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4460#endif
4461#ifdef _PC_SYNC_IO
4462 {"PC_SYNC_IO", _PC_SYNC_IO},
4463#endif
4464#ifdef _PC_VDISABLE
4465 {"PC_VDISABLE", _PC_VDISABLE},
4466#endif
4467};
4468
Fred Drakec9680921999-12-13 16:37:25 +00004469static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004470conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004471{
4472 return conv_confname(arg, valuep, posix_constants_pathconf,
4473 sizeof(posix_constants_pathconf)
4474 / sizeof(struct constdef));
4475}
4476#endif
4477
4478#ifdef HAVE_FPATHCONF
4479static char posix_fpathconf__doc__[] = "\
4480fpathconf(fd, name) -> integer\n\
4481Return the configuration limit name for the file descriptor fd.\n\
4482If there is no limit, return -1.";
4483
4484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004485posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004486{
4487 PyObject *result = NULL;
4488 int name, fd;
4489
Fred Drake12c6e2d1999-12-14 21:25:03 +00004490 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4491 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004492 long limit;
4493
4494 errno = 0;
4495 limit = fpathconf(fd, name);
4496 if (limit == -1 && errno != 0)
4497 posix_error();
4498 else
4499 result = PyInt_FromLong(limit);
4500 }
4501 return result;
4502}
4503#endif
4504
4505
4506#ifdef HAVE_PATHCONF
4507static char posix_pathconf__doc__[] = "\
4508pathconf(path, name) -> integer\n\
4509Return the configuration limit name for the file or directory path.\n\
4510If there is no limit, return -1.";
4511
4512static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004513posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004514{
4515 PyObject *result = NULL;
4516 int name;
4517 char *path;
4518
4519 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4520 conv_path_confname, &name)) {
4521 long limit;
4522
4523 errno = 0;
4524 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004525 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004526 if (errno == EINVAL)
4527 /* could be a path or name problem */
4528 posix_error();
4529 else
4530 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004531 }
Fred Drakec9680921999-12-13 16:37:25 +00004532 else
4533 result = PyInt_FromLong(limit);
4534 }
4535 return result;
4536}
4537#endif
4538
4539#ifdef HAVE_CONFSTR
4540static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004541#ifdef _CS_ARCHITECTURE
4542 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4543#endif
4544#ifdef _CS_HOSTNAME
4545 {"CS_HOSTNAME", _CS_HOSTNAME},
4546#endif
4547#ifdef _CS_HW_PROVIDER
4548 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4549#endif
4550#ifdef _CS_HW_SERIAL
4551 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4552#endif
4553#ifdef _CS_INITTAB_NAME
4554 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4555#endif
Fred Drakec9680921999-12-13 16:37:25 +00004556#ifdef _CS_LFS64_CFLAGS
4557 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4558#endif
4559#ifdef _CS_LFS64_LDFLAGS
4560 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4561#endif
4562#ifdef _CS_LFS64_LIBS
4563 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4564#endif
4565#ifdef _CS_LFS64_LINTFLAGS
4566 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4567#endif
4568#ifdef _CS_LFS_CFLAGS
4569 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4570#endif
4571#ifdef _CS_LFS_LDFLAGS
4572 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4573#endif
4574#ifdef _CS_LFS_LIBS
4575 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4576#endif
4577#ifdef _CS_LFS_LINTFLAGS
4578 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4579#endif
Fred Draked86ed291999-12-15 15:34:33 +00004580#ifdef _CS_MACHINE
4581 {"CS_MACHINE", _CS_MACHINE},
4582#endif
Fred Drakec9680921999-12-13 16:37:25 +00004583#ifdef _CS_PATH
4584 {"CS_PATH", _CS_PATH},
4585#endif
Fred Draked86ed291999-12-15 15:34:33 +00004586#ifdef _CS_RELEASE
4587 {"CS_RELEASE", _CS_RELEASE},
4588#endif
4589#ifdef _CS_SRPC_DOMAIN
4590 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4591#endif
4592#ifdef _CS_SYSNAME
4593 {"CS_SYSNAME", _CS_SYSNAME},
4594#endif
4595#ifdef _CS_VERSION
4596 {"CS_VERSION", _CS_VERSION},
4597#endif
Fred Drakec9680921999-12-13 16:37:25 +00004598#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4599 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4600#endif
4601#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4602 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4603#endif
4604#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4605 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4606#endif
4607#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4608 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4609#endif
4610#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4611 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4612#endif
4613#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4614 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4615#endif
4616#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4617 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4618#endif
4619#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4620 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4621#endif
4622#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4623 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4624#endif
4625#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4626 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4627#endif
4628#ifdef _CS_XBS5_LP64_OFF64_LIBS
4629 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4630#endif
4631#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4632 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4633#endif
4634#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4635 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4636#endif
4637#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4638 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4639#endif
4640#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4641 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4642#endif
4643#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4644 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4645#endif
Fred Draked86ed291999-12-15 15:34:33 +00004646#ifdef _MIPS_CS_AVAIL_PROCESSORS
4647 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4648#endif
4649#ifdef _MIPS_CS_BASE
4650 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4651#endif
4652#ifdef _MIPS_CS_HOSTID
4653 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4654#endif
4655#ifdef _MIPS_CS_HW_NAME
4656 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4657#endif
4658#ifdef _MIPS_CS_NUM_PROCESSORS
4659 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4660#endif
4661#ifdef _MIPS_CS_OSREL_MAJ
4662 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4663#endif
4664#ifdef _MIPS_CS_OSREL_MIN
4665 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4666#endif
4667#ifdef _MIPS_CS_OSREL_PATCH
4668 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4669#endif
4670#ifdef _MIPS_CS_OS_NAME
4671 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4672#endif
4673#ifdef _MIPS_CS_OS_PROVIDER
4674 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4675#endif
4676#ifdef _MIPS_CS_PROCESSORS
4677 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4678#endif
4679#ifdef _MIPS_CS_SERIAL
4680 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4681#endif
4682#ifdef _MIPS_CS_VENDOR
4683 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4684#endif
Fred Drakec9680921999-12-13 16:37:25 +00004685};
4686
4687static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004688conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004689{
4690 return conv_confname(arg, valuep, posix_constants_confstr,
4691 sizeof(posix_constants_confstr)
4692 / sizeof(struct constdef));
4693}
4694
4695static char posix_confstr__doc__[] = "\
4696confstr(name) -> string\n\
4697Return a string-valued system configuration variable.";
4698
4699static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004700posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004701{
4702 PyObject *result = NULL;
4703 int name;
4704 char buffer[64];
4705
4706 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4707 int len = confstr(name, buffer, sizeof(buffer));
4708
Fred Drakec9680921999-12-13 16:37:25 +00004709 errno = 0;
4710 if (len == 0) {
4711 if (errno != 0)
4712 posix_error();
4713 else
4714 result = PyString_FromString("");
4715 }
4716 else {
4717 if (len >= sizeof(buffer)) {
4718 result = PyString_FromStringAndSize(NULL, len);
4719 if (result != NULL)
4720 confstr(name, PyString_AS_STRING(result), len+1);
4721 }
4722 else
4723 result = PyString_FromString(buffer);
4724 }
4725 }
4726 return result;
4727}
4728#endif
4729
4730
4731#ifdef HAVE_SYSCONF
4732static struct constdef posix_constants_sysconf[] = {
4733#ifdef _SC_2_CHAR_TERM
4734 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4735#endif
4736#ifdef _SC_2_C_BIND
4737 {"SC_2_C_BIND", _SC_2_C_BIND},
4738#endif
4739#ifdef _SC_2_C_DEV
4740 {"SC_2_C_DEV", _SC_2_C_DEV},
4741#endif
4742#ifdef _SC_2_C_VERSION
4743 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4744#endif
4745#ifdef _SC_2_FORT_DEV
4746 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4747#endif
4748#ifdef _SC_2_FORT_RUN
4749 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4750#endif
4751#ifdef _SC_2_LOCALEDEF
4752 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4753#endif
4754#ifdef _SC_2_SW_DEV
4755 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4756#endif
4757#ifdef _SC_2_UPE
4758 {"SC_2_UPE", _SC_2_UPE},
4759#endif
4760#ifdef _SC_2_VERSION
4761 {"SC_2_VERSION", _SC_2_VERSION},
4762#endif
Fred Draked86ed291999-12-15 15:34:33 +00004763#ifdef _SC_ABI_ASYNCHRONOUS_IO
4764 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4765#endif
4766#ifdef _SC_ACL
4767 {"SC_ACL", _SC_ACL},
4768#endif
Fred Drakec9680921999-12-13 16:37:25 +00004769#ifdef _SC_AIO_LISTIO_MAX
4770 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4771#endif
Fred Drakec9680921999-12-13 16:37:25 +00004772#ifdef _SC_AIO_MAX
4773 {"SC_AIO_MAX", _SC_AIO_MAX},
4774#endif
4775#ifdef _SC_AIO_PRIO_DELTA_MAX
4776 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4777#endif
4778#ifdef _SC_ARG_MAX
4779 {"SC_ARG_MAX", _SC_ARG_MAX},
4780#endif
4781#ifdef _SC_ASYNCHRONOUS_IO
4782 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4783#endif
4784#ifdef _SC_ATEXIT_MAX
4785 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4786#endif
Fred Draked86ed291999-12-15 15:34:33 +00004787#ifdef _SC_AUDIT
4788 {"SC_AUDIT", _SC_AUDIT},
4789#endif
Fred Drakec9680921999-12-13 16:37:25 +00004790#ifdef _SC_AVPHYS_PAGES
4791 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4792#endif
4793#ifdef _SC_BC_BASE_MAX
4794 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4795#endif
4796#ifdef _SC_BC_DIM_MAX
4797 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4798#endif
4799#ifdef _SC_BC_SCALE_MAX
4800 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4801#endif
4802#ifdef _SC_BC_STRING_MAX
4803 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4804#endif
Fred Draked86ed291999-12-15 15:34:33 +00004805#ifdef _SC_CAP
4806 {"SC_CAP", _SC_CAP},
4807#endif
Fred Drakec9680921999-12-13 16:37:25 +00004808#ifdef _SC_CHARCLASS_NAME_MAX
4809 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4810#endif
4811#ifdef _SC_CHAR_BIT
4812 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4813#endif
4814#ifdef _SC_CHAR_MAX
4815 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4816#endif
4817#ifdef _SC_CHAR_MIN
4818 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4819#endif
4820#ifdef _SC_CHILD_MAX
4821 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4822#endif
4823#ifdef _SC_CLK_TCK
4824 {"SC_CLK_TCK", _SC_CLK_TCK},
4825#endif
4826#ifdef _SC_COHER_BLKSZ
4827 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4828#endif
4829#ifdef _SC_COLL_WEIGHTS_MAX
4830 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4831#endif
4832#ifdef _SC_DCACHE_ASSOC
4833 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4834#endif
4835#ifdef _SC_DCACHE_BLKSZ
4836 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4837#endif
4838#ifdef _SC_DCACHE_LINESZ
4839 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4840#endif
4841#ifdef _SC_DCACHE_SZ
4842 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4843#endif
4844#ifdef _SC_DCACHE_TBLKSZ
4845 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4846#endif
4847#ifdef _SC_DELAYTIMER_MAX
4848 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4849#endif
4850#ifdef _SC_EQUIV_CLASS_MAX
4851 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4852#endif
4853#ifdef _SC_EXPR_NEST_MAX
4854 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4855#endif
4856#ifdef _SC_FSYNC
4857 {"SC_FSYNC", _SC_FSYNC},
4858#endif
4859#ifdef _SC_GETGR_R_SIZE_MAX
4860 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4861#endif
4862#ifdef _SC_GETPW_R_SIZE_MAX
4863 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4864#endif
4865#ifdef _SC_ICACHE_ASSOC
4866 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4867#endif
4868#ifdef _SC_ICACHE_BLKSZ
4869 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4870#endif
4871#ifdef _SC_ICACHE_LINESZ
4872 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4873#endif
4874#ifdef _SC_ICACHE_SZ
4875 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4876#endif
Fred Draked86ed291999-12-15 15:34:33 +00004877#ifdef _SC_INF
4878 {"SC_INF", _SC_INF},
4879#endif
Fred Drakec9680921999-12-13 16:37:25 +00004880#ifdef _SC_INT_MAX
4881 {"SC_INT_MAX", _SC_INT_MAX},
4882#endif
4883#ifdef _SC_INT_MIN
4884 {"SC_INT_MIN", _SC_INT_MIN},
4885#endif
4886#ifdef _SC_IOV_MAX
4887 {"SC_IOV_MAX", _SC_IOV_MAX},
4888#endif
Fred Draked86ed291999-12-15 15:34:33 +00004889#ifdef _SC_IP_SECOPTS
4890 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4891#endif
Fred Drakec9680921999-12-13 16:37:25 +00004892#ifdef _SC_JOB_CONTROL
4893 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4894#endif
Fred Draked86ed291999-12-15 15:34:33 +00004895#ifdef _SC_KERN_POINTERS
4896 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4897#endif
4898#ifdef _SC_KERN_SIM
4899 {"SC_KERN_SIM", _SC_KERN_SIM},
4900#endif
Fred Drakec9680921999-12-13 16:37:25 +00004901#ifdef _SC_LINE_MAX
4902 {"SC_LINE_MAX", _SC_LINE_MAX},
4903#endif
4904#ifdef _SC_LOGIN_NAME_MAX
4905 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4906#endif
4907#ifdef _SC_LOGNAME_MAX
4908 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4909#endif
4910#ifdef _SC_LONG_BIT
4911 {"SC_LONG_BIT", _SC_LONG_BIT},
4912#endif
Fred Draked86ed291999-12-15 15:34:33 +00004913#ifdef _SC_MAC
4914 {"SC_MAC", _SC_MAC},
4915#endif
Fred Drakec9680921999-12-13 16:37:25 +00004916#ifdef _SC_MAPPED_FILES
4917 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4918#endif
4919#ifdef _SC_MAXPID
4920 {"SC_MAXPID", _SC_MAXPID},
4921#endif
4922#ifdef _SC_MB_LEN_MAX
4923 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4924#endif
4925#ifdef _SC_MEMLOCK
4926 {"SC_MEMLOCK", _SC_MEMLOCK},
4927#endif
4928#ifdef _SC_MEMLOCK_RANGE
4929 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4930#endif
4931#ifdef _SC_MEMORY_PROTECTION
4932 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4933#endif
4934#ifdef _SC_MESSAGE_PASSING
4935 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4936#endif
Fred Draked86ed291999-12-15 15:34:33 +00004937#ifdef _SC_MMAP_FIXED_ALIGNMENT
4938 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4939#endif
Fred Drakec9680921999-12-13 16:37:25 +00004940#ifdef _SC_MQ_OPEN_MAX
4941 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4942#endif
4943#ifdef _SC_MQ_PRIO_MAX
4944 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4945#endif
Fred Draked86ed291999-12-15 15:34:33 +00004946#ifdef _SC_NACLS_MAX
4947 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4948#endif
Fred Drakec9680921999-12-13 16:37:25 +00004949#ifdef _SC_NGROUPS_MAX
4950 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4951#endif
4952#ifdef _SC_NL_ARGMAX
4953 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4954#endif
4955#ifdef _SC_NL_LANGMAX
4956 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4957#endif
4958#ifdef _SC_NL_MSGMAX
4959 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4960#endif
4961#ifdef _SC_NL_NMAX
4962 {"SC_NL_NMAX", _SC_NL_NMAX},
4963#endif
4964#ifdef _SC_NL_SETMAX
4965 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4966#endif
4967#ifdef _SC_NL_TEXTMAX
4968 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4969#endif
4970#ifdef _SC_NPROCESSORS_CONF
4971 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4972#endif
4973#ifdef _SC_NPROCESSORS_ONLN
4974 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4975#endif
Fred Draked86ed291999-12-15 15:34:33 +00004976#ifdef _SC_NPROC_CONF
4977 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4978#endif
4979#ifdef _SC_NPROC_ONLN
4980 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4981#endif
Fred Drakec9680921999-12-13 16:37:25 +00004982#ifdef _SC_NZERO
4983 {"SC_NZERO", _SC_NZERO},
4984#endif
4985#ifdef _SC_OPEN_MAX
4986 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4987#endif
4988#ifdef _SC_PAGESIZE
4989 {"SC_PAGESIZE", _SC_PAGESIZE},
4990#endif
4991#ifdef _SC_PAGE_SIZE
4992 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4993#endif
4994#ifdef _SC_PASS_MAX
4995 {"SC_PASS_MAX", _SC_PASS_MAX},
4996#endif
4997#ifdef _SC_PHYS_PAGES
4998 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4999#endif
5000#ifdef _SC_PII
5001 {"SC_PII", _SC_PII},
5002#endif
5003#ifdef _SC_PII_INTERNET
5004 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5005#endif
5006#ifdef _SC_PII_INTERNET_DGRAM
5007 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5008#endif
5009#ifdef _SC_PII_INTERNET_STREAM
5010 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5011#endif
5012#ifdef _SC_PII_OSI
5013 {"SC_PII_OSI", _SC_PII_OSI},
5014#endif
5015#ifdef _SC_PII_OSI_CLTS
5016 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5017#endif
5018#ifdef _SC_PII_OSI_COTS
5019 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5020#endif
5021#ifdef _SC_PII_OSI_M
5022 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5023#endif
5024#ifdef _SC_PII_SOCKET
5025 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5026#endif
5027#ifdef _SC_PII_XTI
5028 {"SC_PII_XTI", _SC_PII_XTI},
5029#endif
5030#ifdef _SC_POLL
5031 {"SC_POLL", _SC_POLL},
5032#endif
5033#ifdef _SC_PRIORITIZED_IO
5034 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5035#endif
5036#ifdef _SC_PRIORITY_SCHEDULING
5037 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5038#endif
5039#ifdef _SC_REALTIME_SIGNALS
5040 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5041#endif
5042#ifdef _SC_RE_DUP_MAX
5043 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5044#endif
5045#ifdef _SC_RTSIG_MAX
5046 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5047#endif
5048#ifdef _SC_SAVED_IDS
5049 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5050#endif
5051#ifdef _SC_SCHAR_MAX
5052 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5053#endif
5054#ifdef _SC_SCHAR_MIN
5055 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5056#endif
5057#ifdef _SC_SELECT
5058 {"SC_SELECT", _SC_SELECT},
5059#endif
5060#ifdef _SC_SEMAPHORES
5061 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5062#endif
5063#ifdef _SC_SEM_NSEMS_MAX
5064 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5065#endif
5066#ifdef _SC_SEM_VALUE_MAX
5067 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5068#endif
5069#ifdef _SC_SHARED_MEMORY_OBJECTS
5070 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5071#endif
5072#ifdef _SC_SHRT_MAX
5073 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5074#endif
5075#ifdef _SC_SHRT_MIN
5076 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5077#endif
5078#ifdef _SC_SIGQUEUE_MAX
5079 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5080#endif
5081#ifdef _SC_SIGRT_MAX
5082 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5083#endif
5084#ifdef _SC_SIGRT_MIN
5085 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5086#endif
Fred Draked86ed291999-12-15 15:34:33 +00005087#ifdef _SC_SOFTPOWER
5088 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5089#endif
Fred Drakec9680921999-12-13 16:37:25 +00005090#ifdef _SC_SPLIT_CACHE
5091 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5092#endif
5093#ifdef _SC_SSIZE_MAX
5094 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5095#endif
5096#ifdef _SC_STACK_PROT
5097 {"SC_STACK_PROT", _SC_STACK_PROT},
5098#endif
5099#ifdef _SC_STREAM_MAX
5100 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5101#endif
5102#ifdef _SC_SYNCHRONIZED_IO
5103 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5104#endif
5105#ifdef _SC_THREADS
5106 {"SC_THREADS", _SC_THREADS},
5107#endif
5108#ifdef _SC_THREAD_ATTR_STACKADDR
5109 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5110#endif
5111#ifdef _SC_THREAD_ATTR_STACKSIZE
5112 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5113#endif
5114#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5115 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5116#endif
5117#ifdef _SC_THREAD_KEYS_MAX
5118 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5119#endif
5120#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5121 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5122#endif
5123#ifdef _SC_THREAD_PRIO_INHERIT
5124 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5125#endif
5126#ifdef _SC_THREAD_PRIO_PROTECT
5127 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5128#endif
5129#ifdef _SC_THREAD_PROCESS_SHARED
5130 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5131#endif
5132#ifdef _SC_THREAD_SAFE_FUNCTIONS
5133 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5134#endif
5135#ifdef _SC_THREAD_STACK_MIN
5136 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5137#endif
5138#ifdef _SC_THREAD_THREADS_MAX
5139 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5140#endif
5141#ifdef _SC_TIMERS
5142 {"SC_TIMERS", _SC_TIMERS},
5143#endif
5144#ifdef _SC_TIMER_MAX
5145 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5146#endif
5147#ifdef _SC_TTY_NAME_MAX
5148 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5149#endif
5150#ifdef _SC_TZNAME_MAX
5151 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5152#endif
5153#ifdef _SC_T_IOV_MAX
5154 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5155#endif
5156#ifdef _SC_UCHAR_MAX
5157 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5158#endif
5159#ifdef _SC_UINT_MAX
5160 {"SC_UINT_MAX", _SC_UINT_MAX},
5161#endif
5162#ifdef _SC_UIO_MAXIOV
5163 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5164#endif
5165#ifdef _SC_ULONG_MAX
5166 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5167#endif
5168#ifdef _SC_USHRT_MAX
5169 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5170#endif
5171#ifdef _SC_VERSION
5172 {"SC_VERSION", _SC_VERSION},
5173#endif
5174#ifdef _SC_WORD_BIT
5175 {"SC_WORD_BIT", _SC_WORD_BIT},
5176#endif
5177#ifdef _SC_XBS5_ILP32_OFF32
5178 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5179#endif
5180#ifdef _SC_XBS5_ILP32_OFFBIG
5181 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5182#endif
5183#ifdef _SC_XBS5_LP64_OFF64
5184 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5185#endif
5186#ifdef _SC_XBS5_LPBIG_OFFBIG
5187 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5188#endif
5189#ifdef _SC_XOPEN_CRYPT
5190 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5191#endif
5192#ifdef _SC_XOPEN_ENH_I18N
5193 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5194#endif
5195#ifdef _SC_XOPEN_LEGACY
5196 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5197#endif
5198#ifdef _SC_XOPEN_REALTIME
5199 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5200#endif
5201#ifdef _SC_XOPEN_REALTIME_THREADS
5202 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5203#endif
5204#ifdef _SC_XOPEN_SHM
5205 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5206#endif
5207#ifdef _SC_XOPEN_UNIX
5208 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5209#endif
5210#ifdef _SC_XOPEN_VERSION
5211 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5212#endif
5213#ifdef _SC_XOPEN_XCU_VERSION
5214 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5215#endif
5216#ifdef _SC_XOPEN_XPG2
5217 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5218#endif
5219#ifdef _SC_XOPEN_XPG3
5220 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5221#endif
5222#ifdef _SC_XOPEN_XPG4
5223 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5224#endif
5225};
5226
5227static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005228conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005229{
5230 return conv_confname(arg, valuep, posix_constants_sysconf,
5231 sizeof(posix_constants_sysconf)
5232 / sizeof(struct constdef));
5233}
5234
5235static char posix_sysconf__doc__[] = "\
5236sysconf(name) -> integer\n\
5237Return an integer-valued system configuration variable.";
5238
5239static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005240posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005241{
5242 PyObject *result = NULL;
5243 int name;
5244
5245 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5246 int value;
5247
5248 errno = 0;
5249 value = sysconf(name);
5250 if (value == -1 && errno != 0)
5251 posix_error();
5252 else
5253 result = PyInt_FromLong(value);
5254 }
5255 return result;
5256}
5257#endif
5258
5259
Fred Drakebec628d1999-12-15 18:31:10 +00005260/* This code is used to ensure that the tables of configuration value names
5261 * are in sorted order as required by conv_confname(), and also to build the
5262 * the exported dictionaries that are used to publish information about the
5263 * names available on the host platform.
5264 *
5265 * Sorting the table at runtime ensures that the table is properly ordered
5266 * when used, even for platforms we're not able to test on. It also makes
5267 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005268 */
Fred Drakebec628d1999-12-15 18:31:10 +00005269
5270static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005271cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005272{
5273 const struct constdef *c1 =
5274 (const struct constdef *) v1;
5275 const struct constdef *c2 =
5276 (const struct constdef *) v2;
5277
5278 return strcmp(c1->name, c2->name);
5279}
5280
5281static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005282setup_confname_table(struct constdef *table, size_t tablesize,
5283 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005284{
Fred Drakebec628d1999-12-15 18:31:10 +00005285 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005286 size_t i;
5287 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005288
5289 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5290 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005291 if (d == NULL)
5292 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005293
Barry Warsaw3155db32000-04-13 15:20:40 +00005294 for (i=0; i < tablesize; ++i) {
5295 PyObject *o = PyInt_FromLong(table[i].value);
5296 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5297 Py_XDECREF(o);
5298 Py_DECREF(d);
5299 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005300 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005301 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005302 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005303 status = PyDict_SetItemString(moddict, tablename, d);
5304 Py_DECREF(d);
5305 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005306}
5307
Fred Drakebec628d1999-12-15 18:31:10 +00005308/* Return -1 on failure, 0 on success. */
5309static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005310setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005311{
5312#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005313 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005314 sizeof(posix_constants_pathconf)
5315 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005316 "pathconf_names", moddict))
5317 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005318#endif
5319#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005320 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005321 sizeof(posix_constants_confstr)
5322 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005323 "confstr_names", moddict))
5324 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005325#endif
5326#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005327 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005328 sizeof(posix_constants_sysconf)
5329 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005330 "sysconf_names", moddict))
5331 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005332#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005333 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005334}
Fred Draked86ed291999-12-15 15:34:33 +00005335
5336
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005337static char posix_abort__doc__[] = "\
5338abort() -> does not return!\n\
5339Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5340in the hardest way possible on the hosting operating system.";
5341
5342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005343posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005344{
5345 if (!PyArg_ParseTuple(args, ":abort"))
5346 return NULL;
5347 abort();
5348 /*NOTREACHED*/
5349 Py_FatalError("abort() called from Python code didn't abort!");
5350 return NULL;
5351}
Fred Drakebec628d1999-12-15 18:31:10 +00005352
Tim Petersf58a7aa2000-09-22 10:05:54 +00005353#ifdef MS_WIN32
5354static char win32_startfile__doc__[] = "\
5355startfile(filepath) - Start a file with its associated application.\n\
5356\n\
5357This acts like double-clicking the file in Explorer, or giving the file\n\
5358name as an argument to the DOS \"start\" command: the file is opened\n\
5359with whatever application (if any) its extension is associated.\n\
5360\n\
5361startfile returns as soon as the associated application is launched.\n\
5362There is no option to wait for the application to close, and no way\n\
5363to retrieve the application's exit status.\n\
5364\n\
5365The filepath is relative to the current directory. If you want to use\n\
5366an absolute path, make sure the first character is not a slash (\"/\");\n\
5367the underlying Win32 ShellExecute function doesn't work if it is.";
5368
5369static PyObject *
5370win32_startfile(PyObject *self, PyObject *args)
5371{
5372 char *filepath;
5373 HINSTANCE rc;
5374 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5375 return NULL;
5376 Py_BEGIN_ALLOW_THREADS
5377 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5378 Py_END_ALLOW_THREADS
5379 if (rc <= (HINSTANCE)32)
5380 return win32_error("startfile", filepath);
5381 Py_INCREF(Py_None);
5382 return Py_None;
5383}
5384#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005385
5386static PyMethodDef posix_methods[] = {
5387 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5388#ifdef HAVE_TTYNAME
5389 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5390#endif
5391 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5392 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005393#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005394 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005395#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005396#ifdef HAVE_CHROOT
5397 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5398#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005399#ifdef HAVE_CTERMID
5400 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5401#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005402#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005403 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005404#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005405#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005406 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005407#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005408 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5409 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5410 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005411#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005412 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005413#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005414#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005415 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005416#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005417 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5418 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5419 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005420#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005421 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005422#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005423#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005424 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005425#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005426 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005427#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005428 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005429#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005430 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5431 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5432 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005433#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005434 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005435#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005436 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005437#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005438 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5439 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005440#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005441#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005442 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5443 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005444#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005445#ifdef HAVE_FORK1
5446 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5447#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005448#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005449 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005450#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005451#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005452 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005453#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005454#ifdef HAVE_FORKPTY
5455 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5456#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005457#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005458 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005459#endif /* HAVE_GETEGID */
5460#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005461 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005462#endif /* HAVE_GETEUID */
5463#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005464 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005465#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005466#ifdef HAVE_GETGROUPS
5467 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5468#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005469 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005470#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005471 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005472#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005473#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005474 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005475#endif /* HAVE_GETPPID */
5476#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005477 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005478#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005479#ifdef HAVE_GETLOGIN
5480 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5481#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005482#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005483 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005484#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005485#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005486 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005487#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005488#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005489 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005490#ifdef MS_WIN32
5491 {"popen2", win32_popen2, METH_VARARGS},
5492 {"popen3", win32_popen3, METH_VARARGS},
5493 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005494 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005495#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005496#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005497#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005498 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005499#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005500#ifdef HAVE_SETEUID
5501 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5502#endif /* HAVE_SETEUID */
5503#ifdef HAVE_SETEGID
5504 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5505#endif /* HAVE_SETEGID */
5506#ifdef HAVE_SETREUID
5507 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5508#endif /* HAVE_SETREUID */
5509#ifdef HAVE_SETREGID
5510 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5511#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005512#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005513 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005514#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005515#ifdef HAVE_SETGROUPS
5516 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5517#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005518#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005519 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005520#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005521#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005522 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005523#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005524#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005525 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005526#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005527#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005528 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005529#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005530#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005531 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005532#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005533#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005534 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005535#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005536#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005537 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005538#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005539 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5540 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5541 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5542 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5543 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5544 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5545 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5546 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5547 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005548 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005549#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005550 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005551#endif
5552#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005553 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005554#endif
5555#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005556 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005557#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005558#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005559 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005560#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005561#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005562 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005563#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005564#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005565 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005566#endif
5567#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005568 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005569#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005570#ifdef HAVE_SYS_WAIT_H
5571#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005572 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005573#endif /* WIFSTOPPED */
5574#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005575 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005576#endif /* WIFSIGNALED */
5577#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005578 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005579#endif /* WIFEXITED */
5580#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005581 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005582#endif /* WEXITSTATUS */
5583#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005584 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005585#endif /* WTERMSIG */
5586#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005587 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005588#endif /* WSTOPSIG */
5589#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005590#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005591 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005592#endif
5593#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005594 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005595#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005596#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005597 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5598#endif
5599#ifdef HAVE_TEMPNAM
5600 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5601#endif
5602#ifdef HAVE_TMPNAM
5603 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5604#endif
Fred Drakec9680921999-12-13 16:37:25 +00005605#ifdef HAVE_CONFSTR
5606 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5607#endif
5608#ifdef HAVE_SYSCONF
5609 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5610#endif
5611#ifdef HAVE_FPATHCONF
5612 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5613#endif
5614#ifdef HAVE_PATHCONF
5615 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5616#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005617 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005618#ifdef MS_WIN32
5619 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5620#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005621 {NULL, NULL} /* Sentinel */
5622};
5623
5624
Barry Warsaw4a342091996-12-19 23:50:02 +00005625static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005626ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005627{
5628 PyObject* v = PyInt_FromLong(value);
5629 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5630 return -1; /* triggers fatal error */
5631
5632 Py_DECREF(v);
5633 return 0;
5634}
5635
Guido van Rossumd48f2521997-12-05 22:19:34 +00005636#if defined(PYOS_OS2)
5637/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5638static int insertvalues(PyObject *d)
5639{
5640 APIRET rc;
5641 ULONG values[QSV_MAX+1];
5642 PyObject *v;
5643 char *ver, tmp[10];
5644
5645 Py_BEGIN_ALLOW_THREADS
5646 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5647 Py_END_ALLOW_THREADS
5648
5649 if (rc != NO_ERROR) {
5650 os2_error(rc);
5651 return -1;
5652 }
5653
5654 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5655 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5656 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5657 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5658 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5659 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5660 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5661
5662 switch (values[QSV_VERSION_MINOR]) {
5663 case 0: ver = "2.00"; break;
5664 case 10: ver = "2.10"; break;
5665 case 11: ver = "2.11"; break;
5666 case 30: ver = "3.00"; break;
5667 case 40: ver = "4.00"; break;
5668 case 50: ver = "5.00"; break;
5669 default:
5670 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5671 values[QSV_VERSION_MINOR]);
5672 ver = &tmp[0];
5673 }
5674
5675 /* Add Indicator of the Version of the Operating System */
5676 v = PyString_FromString(ver);
5677 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5678 return -1;
5679 Py_DECREF(v);
5680
5681 /* Add Indicator of Which Drive was Used to Boot the System */
5682 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5683 tmp[1] = ':';
5684 tmp[2] = '\0';
5685
5686 v = PyString_FromString(tmp);
5687 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5688 return -1;
5689 Py_DECREF(v);
5690
5691 return 0;
5692}
5693#endif
5694
Barry Warsaw4a342091996-12-19 23:50:02 +00005695static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005696all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005697{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005698#ifdef F_OK
5699 if (ins(d, "F_OK", (long)F_OK)) return -1;
5700#endif
5701#ifdef R_OK
5702 if (ins(d, "R_OK", (long)R_OK)) return -1;
5703#endif
5704#ifdef W_OK
5705 if (ins(d, "W_OK", (long)W_OK)) return -1;
5706#endif
5707#ifdef X_OK
5708 if (ins(d, "X_OK", (long)X_OK)) return -1;
5709#endif
Fred Drakec9680921999-12-13 16:37:25 +00005710#ifdef NGROUPS_MAX
5711 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5712#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005713#ifdef TMP_MAX
5714 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5715#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005716#ifdef WNOHANG
5717 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5718#endif
5719#ifdef O_RDONLY
5720 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5721#endif
5722#ifdef O_WRONLY
5723 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5724#endif
5725#ifdef O_RDWR
5726 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5727#endif
5728#ifdef O_NDELAY
5729 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5730#endif
5731#ifdef O_NONBLOCK
5732 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5733#endif
5734#ifdef O_APPEND
5735 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5736#endif
5737#ifdef O_DSYNC
5738 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5739#endif
5740#ifdef O_RSYNC
5741 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5742#endif
5743#ifdef O_SYNC
5744 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5745#endif
5746#ifdef O_NOCTTY
5747 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5748#endif
5749#ifdef O_CREAT
5750 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5751#endif
5752#ifdef O_EXCL
5753 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5754#endif
5755#ifdef O_TRUNC
5756 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5757#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005758#ifdef O_BINARY
5759 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5760#endif
5761#ifdef O_TEXT
5762 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5763#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005764
Guido van Rossum246bc171999-02-01 23:54:31 +00005765#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005766 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5767 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5768 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5769 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5770 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005771#endif
5772
Guido van Rossumd48f2521997-12-05 22:19:34 +00005773#if defined(PYOS_OS2)
5774 if (insertvalues(d)) return -1;
5775#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005776 return 0;
5777}
5778
5779
Tim Peters58e0a8c2001-05-14 22:32:33 +00005780#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005781#define INITFUNC initnt
5782#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005783
5784#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005785#define INITFUNC initos2
5786#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005787
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005788#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005789#define INITFUNC initposix
5790#define MODNAME "posix"
5791#endif
5792
Guido van Rossum3886bb61998-12-04 18:50:17 +00005793DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005794INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005795{
Barry Warsaw53699e91996-12-10 23:23:01 +00005796 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005797
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005798 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005799 posix_methods,
5800 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005801 (PyObject *)NULL,
5802 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005803 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005804
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005805 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005806 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005807 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005808 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005809 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005810
Barry Warsaw4a342091996-12-19 23:50:02 +00005811 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005812 return;
5813
Fred Drakebec628d1999-12-15 18:31:10 +00005814 if (setup_confname_tables(d))
5815 return;
5816
Barry Warsawca74da41999-02-09 19:31:45 +00005817 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005818
Guido van Rossumb3d39562000-01-31 18:41:26 +00005819#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005820 if (posix_putenv_garbage == NULL)
5821 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005822#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005823}