blob: 5f6f21d39f9d0b232d23f22532505647aa59edec [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
Fred Drake699f3522000-06-29 21:12:41 +0000267#ifdef MS_WIN64
268# 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
Guido van Rossum21142a01999-01-08 21:05:37 +0000727#ifdef HAVE_FSYNC
728static char posix_fsync__doc__[] =
729"fsync(fildes) -> None\n\
730force write of file with filedescriptor to disk.";
731
732static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000733posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000734{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000735 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000736}
737#endif /* HAVE_FSYNC */
738
739#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000740
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000741#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000742extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
743#endif
744
Guido van Rossum21142a01999-01-08 21:05:37 +0000745static char posix_fdatasync__doc__[] =
746"fdatasync(fildes) -> None\n\
747force write of file with filedescriptor to disk.\n\
748 does not force update of metadata.";
749
750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000751posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000752{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000753 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000754}
755#endif /* HAVE_FDATASYNC */
756
757
Fredrik Lundh10723342000-07-10 16:38:09 +0000758#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000759static char posix_chown__doc__[] =
760"chown(path, uid, gid) -> None\n\
761Change the owner and group id of path to the numeric uid and gid.";
762
Barry Warsaw53699e91996-12-10 23:23:01 +0000763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000764posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000765{
Mark Hammondef8b6542001-05-13 08:04:26 +0000766 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000767 int uid, gid;
768 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000769 if (!PyArg_ParseTuple(args, "etii:chown",
770 Py_FileSystemDefaultEncoding, &path,
771 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000772 return NULL;
773 Py_BEGIN_ALLOW_THREADS
774 res = chown(path, (uid_t) uid, (gid_t) gid);
775 Py_END_ALLOW_THREADS
776 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000777 return posix_error_with_allocated_filename(path);
778 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000779 Py_INCREF(Py_None);
780 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000781}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000782#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000784
Guido van Rossum36bc6801995-06-14 22:54:23 +0000785#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000786static char posix_getcwd__doc__[] =
787"getcwd() -> path\n\
788Return a string representing the current working directory.";
789
Barry Warsaw53699e91996-12-10 23:23:01 +0000790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000791posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000792{
793 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000794 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000795 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000796 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000797 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000798 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000799 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000800 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000801 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000802 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000803}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000804#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000806
Guido van Rossumb6775db1994-08-01 11:34:53 +0000807#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000808static char posix_link__doc__[] =
809"link(src, dst) -> None\n\
810Create a hard link to a file.";
811
Barry Warsaw53699e91996-12-10 23:23:01 +0000812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000813posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000814{
Mark Hammondef8b6542001-05-13 08:04:26 +0000815 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000816}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000817#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000819
820static char posix_listdir__doc__[] =
821"listdir(path) -> list_of_strings\n\
822Return a list containing the names of the entries in the directory.\n\
823\n\
824 path: path of directory to list\n\
825\n\
826The list is in arbitrary order. It does not include the special\n\
827entries '.' and '..' even if they are present in the directory.";
828
Barry Warsaw53699e91996-12-10 23:23:01 +0000829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000830posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000831{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000832 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000833 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000834#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000835
Barry Warsaw53699e91996-12-10 23:23:01 +0000836 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000837 HANDLE hFindFile;
838 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000839 /* MAX_PATH characters could mean a bigger encoded string */
840 char namebuf[MAX_PATH*2+5];
841 char *bufptr = namebuf;
842 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000843 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000844
Mark Hammondef8b6542001-05-13 08:04:26 +0000845 if (!PyArg_ParseTuple(args, "et#:listdir",
846 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000847 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000848 ch = namebuf[len-1];
849 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000850 namebuf[len++] = '/';
851 strcpy(namebuf + len, "*.*");
852
Barry Warsaw53699e91996-12-10 23:23:01 +0000853 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000854 return NULL;
855
856 hFindFile = FindFirstFile(namebuf, &FileData);
857 if (hFindFile == INVALID_HANDLE_VALUE) {
858 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000859 if (errno == ERROR_FILE_NOT_FOUND)
860 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000861 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000862 }
863 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000864 if (FileData.cFileName[0] == '.' &&
865 (FileData.cFileName[1] == '\0' ||
866 FileData.cFileName[1] == '.' &&
867 FileData.cFileName[2] == '\0'))
868 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000869 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000870 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000871 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000872 d = NULL;
873 break;
874 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000875 if (PyList_Append(d, v) != 0) {
876 Py_DECREF(v);
877 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000878 d = NULL;
879 break;
880 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000881 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000882 } while (FindNextFile(hFindFile, &FileData) == TRUE);
883
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000884 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +0000885 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000886
887 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000888
Tim Peters0bb44a42000-09-15 07:44:49 +0000889#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000890
891#ifndef MAX_PATH
892#define MAX_PATH 250
893#endif
894 char *name, *pt;
895 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000896 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000897 char namebuf[MAX_PATH+5];
898 struct _find_t ep;
899
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000900 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000901 return NULL;
902 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000903 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000904 return NULL;
905 }
906 strcpy(namebuf, name);
907 for (pt = namebuf; *pt; pt++)
908 if (*pt == '/')
909 *pt = '\\';
910 if (namebuf[len-1] != '\\')
911 namebuf[len++] = '\\';
912 strcpy(namebuf + len, "*.*");
913
Barry Warsaw53699e91996-12-10 23:23:01 +0000914 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000915 return NULL;
916
917 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000918 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
919 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000920 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000921 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000922 }
923 do {
924 if (ep.name[0] == '.' &&
925 (ep.name[1] == '\0' ||
926 ep.name[1] == '.' &&
927 ep.name[2] == '\0'))
928 continue;
929 strcpy(namebuf, ep.name);
930 for (pt = namebuf; *pt; pt++)
931 if (isupper(*pt))
932 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000933 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000934 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000935 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000936 d = NULL;
937 break;
938 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000939 if (PyList_Append(d, v) != 0) {
940 Py_DECREF(v);
941 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000942 d = NULL;
943 break;
944 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000945 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000946 } while (_dos_findnext(&ep) == 0);
947
948 return d;
949
Tim Peters0bb44a42000-09-15 07:44:49 +0000950#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000951
952#ifndef MAX_PATH
953#define MAX_PATH CCHMAXPATH
954#endif
955 char *name, *pt;
956 int len;
957 PyObject *d, *v;
958 char namebuf[MAX_PATH+5];
959 HDIR hdir = 1;
960 ULONG srchcnt = 1;
961 FILEFINDBUF3 ep;
962 APIRET rc;
963
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000964 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000965 return NULL;
966 if (len >= MAX_PATH) {
967 PyErr_SetString(PyExc_ValueError, "path too long");
968 return NULL;
969 }
970 strcpy(namebuf, name);
971 for (pt = namebuf; *pt; pt++)
972 if (*pt == '/')
973 *pt = '\\';
974 if (namebuf[len-1] != '\\')
975 namebuf[len++] = '\\';
976 strcpy(namebuf + len, "*.*");
977
978 if ((d = PyList_New(0)) == NULL)
979 return NULL;
980
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000981 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
982 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000983 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000984 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
985 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
986 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000987
988 if (rc != NO_ERROR) {
989 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000990 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000991 }
992
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000993 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000994 do {
995 if (ep.achName[0] == '.'
996 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000997 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000998
999 strcpy(namebuf, ep.achName);
1000
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001001 /* Leave Case of Name Alone -- In Native Form */
1002 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001003
1004 v = PyString_FromString(namebuf);
1005 if (v == NULL) {
1006 Py_DECREF(d);
1007 d = NULL;
1008 break;
1009 }
1010 if (PyList_Append(d, v) != 0) {
1011 Py_DECREF(v);
1012 Py_DECREF(d);
1013 d = NULL;
1014 break;
1015 }
1016 Py_DECREF(v);
1017 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1018 }
1019
1020 return d;
1021#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001022
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001023 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001024 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001025 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001026 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001027 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001028 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001029 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001030 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001031 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001032 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001033 closedir(dirp);
1034 return NULL;
1035 }
1036 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001037 if (ep->d_name[0] == '.' &&
1038 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001039 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001040 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001041 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001042 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001043 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001044 d = NULL;
1045 break;
1046 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001047 if (PyList_Append(d, v) != 0) {
1048 Py_DECREF(v);
1049 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001050 d = NULL;
1051 break;
1052 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001053 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001054 }
1055 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001056
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001057 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001058
Tim Peters0bb44a42000-09-15 07:44:49 +00001059#endif /* which OS */
1060} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061
Mark Hammondef8b6542001-05-13 08:04:26 +00001062#ifdef MS_WIN32
1063/* A helper function for abspath on win32 */
1064static PyObject *
1065posix__getfullpathname(PyObject *self, PyObject *args)
1066{
1067 /* assume encoded strings wont more than double no of chars */
1068 char inbuf[MAX_PATH*2];
1069 char *inbufp = inbuf;
1070 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1071 char outbuf[MAX_PATH*2];
1072 char *temp;
1073 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1074 Py_FileSystemDefaultEncoding, &inbufp,
1075 &insize))
1076 return NULL;
1077 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1078 outbuf, &temp))
1079 return win32_error("GetFullPathName", inbuf);
1080 return PyString_FromString(outbuf);
1081} /* end of posix__getfullpathname */
1082#endif /* MS_WIN32 */
1083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001084static char posix_mkdir__doc__[] =
1085"mkdir(path [, mode=0777]) -> None\n\
1086Create a directory.";
1087
Barry Warsaw53699e91996-12-10 23:23:01 +00001088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001089posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001090{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001091 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001092 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001093 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001094 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1095 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001096 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001097 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001098#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001099 res = mkdir(path);
1100#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001101 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001102#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001103 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001104 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001105 return posix_error_with_allocated_filename(path);
1106 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001107 Py_INCREF(Py_None);
1108 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001109}
1110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001111
Guido van Rossumb6775db1994-08-01 11:34:53 +00001112#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001113#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1114#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1115#include <sys/resource.h>
1116#endif
1117#endif
1118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001119static char posix_nice__doc__[] =
1120"nice(inc) -> new_priority\n\
1121Decrease the priority of process and return new priority.";
1122
Barry Warsaw53699e91996-12-10 23:23:01 +00001123static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001124posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001125{
1126 int increment, value;
1127
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001128 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001129 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001130
1131 /* There are two flavours of 'nice': one that returns the new
1132 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001133 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1134 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001135
1136 If we are of the nice family that returns the new priority, we
1137 need to clear errno before the call, and check if errno is filled
1138 before calling posix_error() on a returnvalue of -1, because the
1139 -1 may be the actual new priority! */
1140
1141 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001142 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001143#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001144 if (value == 0)
1145 value = getpriority(PRIO_PROCESS, 0);
1146#endif
1147 if (value == -1 && errno != 0)
1148 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001149 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001150 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001151}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001152#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001154
1155static char posix_rename__doc__[] =
1156"rename(old, new) -> None\n\
1157Rename a file or directory.";
1158
Barry Warsaw53699e91996-12-10 23:23:01 +00001159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001160posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001161{
Mark Hammondef8b6542001-05-13 08:04:26 +00001162 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001163}
1164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001165
1166static char posix_rmdir__doc__[] =
1167"rmdir(path) -> None\n\
1168Remove a directory.";
1169
Barry Warsaw53699e91996-12-10 23:23:01 +00001170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001171posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001172{
Mark Hammondef8b6542001-05-13 08:04:26 +00001173 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001174}
1175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001176
1177static char posix_stat__doc__[] =
1178"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1179Perform a stat system call on the given path.";
1180
Barry Warsaw53699e91996-12-10 23:23:01 +00001181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001182posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001183{
Mark Hammondef8b6542001-05-13 08:04:26 +00001184 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185}
1186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001187
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001188#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001189static char posix_system__doc__[] =
1190"system(command) -> exit_status\n\
1191Execute the command (a string) in a subshell.";
1192
Barry Warsaw53699e91996-12-10 23:23:01 +00001193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001194posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001196 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001197 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001198 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001199 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001200 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001201 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001202 Py_END_ALLOW_THREADS
1203 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001204}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001205#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001207
1208static char posix_umask__doc__[] =
1209"umask(new_mask) -> old_mask\n\
1210Set the current numeric umask and return the previous umask.";
1211
Barry Warsaw53699e91996-12-10 23:23:01 +00001212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001213posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214{
1215 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001216 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001217 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001218 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001219 if (i < 0)
1220 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001221 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001222}
1223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001224
1225static char posix_unlink__doc__[] =
1226"unlink(path) -> None\n\
1227Remove a file (same as remove(path)).";
1228
1229static char posix_remove__doc__[] =
1230"remove(path) -> None\n\
1231Remove a file (same as unlink(path)).";
1232
Barry Warsaw53699e91996-12-10 23:23:01 +00001233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001234posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001235{
Mark Hammondef8b6542001-05-13 08:04:26 +00001236 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001237}
1238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001239
Guido van Rossumb6775db1994-08-01 11:34:53 +00001240#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001241static char posix_uname__doc__[] =
1242"uname() -> (sysname, nodename, release, version, machine)\n\
1243Return a tuple identifying the current operating system.";
1244
Barry Warsaw53699e91996-12-10 23:23:01 +00001245static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001246posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001247{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001248 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001249 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001250 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001251 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001252 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001253 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001254 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001255 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001256 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001257 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001258 u.sysname,
1259 u.nodename,
1260 u.release,
1261 u.version,
1262 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001263}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001264#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001266
1267static char posix_utime__doc__[] =
1268"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001269utime(path, None) -> None\n\
1270Set the access and modified time of the file to the given values. If the\n\
1271second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001272
Barry Warsaw53699e91996-12-10 23:23:01 +00001273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001274posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001276 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001277 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001278 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001279 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001280
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001281/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001282#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001283 struct utimbuf buf;
1284#define ATIME buf.actime
1285#define MTIME buf.modtime
1286#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001287#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001288 time_t buf[2];
1289#define ATIME buf[0]
1290#define MTIME buf[1]
1291#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001292#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001293
Barry Warsaw3cef8562000-05-01 16:17:24 +00001294 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001295 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001296 if (arg == Py_None) {
1297 /* optional time values not given */
1298 Py_BEGIN_ALLOW_THREADS
1299 res = utime(path, NULL);
1300 Py_END_ALLOW_THREADS
1301 }
1302 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1303 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001304 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001305 return NULL;
1306 }
1307 else {
1308 ATIME = atime;
1309 MTIME = mtime;
1310 Py_BEGIN_ALLOW_THREADS
1311 res = utime(path, UTIME_ARG);
1312 Py_END_ALLOW_THREADS
1313 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001314 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001315 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001316 Py_INCREF(Py_None);
1317 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001318#undef UTIME_ARG
1319#undef ATIME
1320#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001321}
1322
Guido van Rossum85e3b011991-06-03 12:42:10 +00001323
Guido van Rossum3b066191991-06-04 19:40:25 +00001324/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001326static char posix__exit__doc__[] =
1327"_exit(status)\n\
1328Exit to the system with specified status, without normal exit processing.";
1329
Barry Warsaw53699e91996-12-10 23:23:01 +00001330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001331posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001332{
1333 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001334 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001335 return NULL;
1336 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001337 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001338}
1339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001340
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001341#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001342static char posix_execv__doc__[] =
1343"execv(path, args)\n\
1344Execute an executable path with arguments, replacing current process.\n\
1345\n\
1346 path: path of executable file\n\
1347 args: tuple or list of strings";
1348
Barry Warsaw53699e91996-12-10 23:23:01 +00001349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001350posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001351{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001352 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001353 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001354 char **argvlist;
1355 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001356 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001357
Guido van Rossum89b33251993-10-22 14:26:06 +00001358 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001359 argv is a list or tuple of strings. */
1360
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001361 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001362 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001363 if (PyList_Check(argv)) {
1364 argc = PyList_Size(argv);
1365 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001366 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001367 else if (PyTuple_Check(argv)) {
1368 argc = PyTuple_Size(argv);
1369 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001370 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001371 else {
Fred Drake661ea262000-10-24 19:57:45 +00001372 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001373 return NULL;
1374 }
1375
1376 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001377 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001378 return NULL;
1379 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001380
Barry Warsaw53699e91996-12-10 23:23:01 +00001381 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001382 if (argvlist == NULL)
1383 return NULL;
1384 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001385 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1386 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001387 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001388 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001389 return NULL;
1390
Guido van Rossum85e3b011991-06-03 12:42:10 +00001391 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001392 }
1393 argvlist[argc] = NULL;
1394
Guido van Rossumb6775db1994-08-01 11:34:53 +00001395#ifdef BAD_EXEC_PROTOTYPES
1396 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001397#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001398 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001399#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001400
Guido van Rossum85e3b011991-06-03 12:42:10 +00001401 /* If we get here it's definitely an error */
1402
Barry Warsaw53699e91996-12-10 23:23:01 +00001403 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001404 return posix_error();
1405}
1406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001407
1408static char posix_execve__doc__[] =
1409"execve(path, args, env)\n\
1410Execute a path with arguments and environment, replacing current process.\n\
1411\n\
1412 path: path of executable file\n\
1413 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001414 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001415
Barry Warsaw53699e91996-12-10 23:23:01 +00001416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001417posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001418{
1419 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001420 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001421 char **argvlist;
1422 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001423 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001424 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001425 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001426
1427 /* execve has three arguments: (path, argv, env), where
1428 argv is a list or tuple of strings and env is a dictionary
1429 like posix.environ. */
1430
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001431 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001432 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001433 if (PyList_Check(argv)) {
1434 argc = PyList_Size(argv);
1435 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001436 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001437 else if (PyTuple_Check(argv)) {
1438 argc = PyTuple_Size(argv);
1439 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001440 }
1441 else {
Fred Drake661ea262000-10-24 19:57:45 +00001442 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001443 return NULL;
1444 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001445 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001446 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001447 return NULL;
1448 }
1449
Guido van Rossum50422b42000-04-26 20:34:28 +00001450 if (argc == 0) {
1451 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001452 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001453 return NULL;
1454 }
1455
Barry Warsaw53699e91996-12-10 23:23:01 +00001456 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001457 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001458 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001459 return NULL;
1460 }
1461 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001462 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001463 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001464 &argvlist[i]))
1465 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001466 goto fail_1;
1467 }
1468 }
1469 argvlist[argc] = NULL;
1470
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001471 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001472 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001473 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001474 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001475 goto fail_1;
1476 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001477 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001478 keys = PyMapping_Keys(env);
1479 vals = PyMapping_Values(env);
1480 if (!keys || !vals)
1481 goto fail_2;
1482
1483 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001484 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001485
1486 key = PyList_GetItem(keys, pos);
1487 val = PyList_GetItem(vals, pos);
1488 if (!key || !val)
1489 goto fail_2;
1490
Fred Drake661ea262000-10-24 19:57:45 +00001491 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1492 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001493 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001494 goto fail_2;
1495 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001496
1497#if defined(PYOS_OS2)
1498 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1499 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1500#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001501 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001502 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001503 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001504 goto fail_2;
1505 }
1506 sprintf(p, "%s=%s", k, v);
1507 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001508#if defined(PYOS_OS2)
1509 }
1510#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001511 }
1512 envlist[envc] = 0;
1513
Guido van Rossumb6775db1994-08-01 11:34:53 +00001514
1515#ifdef BAD_EXEC_PROTOTYPES
1516 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001517#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001518 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001519#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001520
1521 /* If we get here it's definitely an error */
1522
1523 (void) posix_error();
1524
1525 fail_2:
1526 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001527 PyMem_DEL(envlist[envc]);
1528 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001529 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001530 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001531 Py_XDECREF(vals);
1532 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001533 return NULL;
1534}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001535#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001537
Guido van Rossuma1065681999-01-25 23:20:23 +00001538#ifdef HAVE_SPAWNV
1539static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001540"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001541Execute an executable path with arguments, replacing current process.\n\
1542\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001543 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001544 path: path of executable file\n\
1545 args: tuple or list of strings";
1546
1547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001548posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001549{
1550 char *path;
1551 PyObject *argv;
1552 char **argvlist;
1553 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001554 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001555 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001556
1557 /* spawnv has three arguments: (mode, path, argv), where
1558 argv is a list or tuple of strings. */
1559
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001560 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001561 return NULL;
1562 if (PyList_Check(argv)) {
1563 argc = PyList_Size(argv);
1564 getitem = PyList_GetItem;
1565 }
1566 else if (PyTuple_Check(argv)) {
1567 argc = PyTuple_Size(argv);
1568 getitem = PyTuple_GetItem;
1569 }
1570 else {
Fred Drake661ea262000-10-24 19:57:45 +00001571 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001572 return NULL;
1573 }
1574
1575 argvlist = PyMem_NEW(char *, argc+1);
1576 if (argvlist == NULL)
1577 return NULL;
1578 for (i = 0; i < argc; i++) {
1579 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1580 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001581 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001582 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001583 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001584 }
1585 }
1586 argvlist[argc] = NULL;
1587
Guido van Rossum246bc171999-02-01 23:54:31 +00001588 if (mode == _OLD_P_OVERLAY)
1589 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001590 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001591
1592 PyMem_DEL(argvlist);
1593
Fred Drake699f3522000-06-29 21:12:41 +00001594 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001595 return posix_error();
1596 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001597#if SIZEOF_LONG == SIZEOF_VOID_P
1598 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001599#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001600 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001601#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001602}
1603
1604
1605static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001606"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001607Execute a path with arguments and environment, replacing current process.\n\
1608\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001609 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001610 path: path of executable file\n\
1611 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001612 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001613
1614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001615posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001616{
1617 char *path;
1618 PyObject *argv, *env;
1619 char **argvlist;
1620 char **envlist;
1621 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1622 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001623 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001624 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001625
1626 /* spawnve has four arguments: (mode, path, argv, env), where
1627 argv is a list or tuple of strings and env is a dictionary
1628 like posix.environ. */
1629
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001630 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001631 return NULL;
1632 if (PyList_Check(argv)) {
1633 argc = PyList_Size(argv);
1634 getitem = PyList_GetItem;
1635 }
1636 else if (PyTuple_Check(argv)) {
1637 argc = PyTuple_Size(argv);
1638 getitem = PyTuple_GetItem;
1639 }
1640 else {
Fred Drake661ea262000-10-24 19:57:45 +00001641 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001642 return NULL;
1643 }
1644 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001645 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001646 return NULL;
1647 }
1648
1649 argvlist = PyMem_NEW(char *, argc+1);
1650 if (argvlist == NULL) {
1651 PyErr_NoMemory();
1652 return NULL;
1653 }
1654 for (i = 0; i < argc; i++) {
1655 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001656 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001657 &argvlist[i]))
1658 {
1659 goto fail_1;
1660 }
1661 }
1662 argvlist[argc] = NULL;
1663
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001664 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001665 envlist = PyMem_NEW(char *, i + 1);
1666 if (envlist == NULL) {
1667 PyErr_NoMemory();
1668 goto fail_1;
1669 }
1670 envc = 0;
1671 keys = PyMapping_Keys(env);
1672 vals = PyMapping_Values(env);
1673 if (!keys || !vals)
1674 goto fail_2;
1675
1676 for (pos = 0; pos < i; pos++) {
1677 char *p, *k, *v;
1678
1679 key = PyList_GetItem(keys, pos);
1680 val = PyList_GetItem(vals, pos);
1681 if (!key || !val)
1682 goto fail_2;
1683
Fred Drake661ea262000-10-24 19:57:45 +00001684 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1685 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001686 {
1687 goto fail_2;
1688 }
1689 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1690 if (p == NULL) {
1691 PyErr_NoMemory();
1692 goto fail_2;
1693 }
1694 sprintf(p, "%s=%s", k, v);
1695 envlist[envc++] = p;
1696 }
1697 envlist[envc] = 0;
1698
Guido van Rossum246bc171999-02-01 23:54:31 +00001699 if (mode == _OLD_P_OVERLAY)
1700 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001701 spawnval = _spawnve(mode, path, argvlist, envlist);
1702 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001703 (void) posix_error();
1704 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001705#if SIZEOF_LONG == SIZEOF_VOID_P
1706 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001707#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001708 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001709#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001710
1711 fail_2:
1712 while (--envc >= 0)
1713 PyMem_DEL(envlist[envc]);
1714 PyMem_DEL(envlist);
1715 fail_1:
1716 PyMem_DEL(argvlist);
1717 Py_XDECREF(vals);
1718 Py_XDECREF(keys);
1719 return res;
1720}
1721#endif /* HAVE_SPAWNV */
1722
1723
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001724#ifdef HAVE_FORK1
1725static char posix_fork1__doc__[] =
1726"fork1() -> pid\n\
1727Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1728\n\
1729Return 0 to child process and PID of child to parent process.";
1730
1731static PyObject *
1732posix_fork1(self, args)
1733 PyObject *self;
1734 PyObject *args;
1735{
1736 int pid;
1737 if (!PyArg_ParseTuple(args, ":fork1"))
1738 return NULL;
1739 pid = fork1();
1740 if (pid == -1)
1741 return posix_error();
1742 PyOS_AfterFork();
1743 return PyInt_FromLong((long)pid);
1744}
1745#endif
1746
1747
Guido van Rossumad0ee831995-03-01 10:34:45 +00001748#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001749static char posix_fork__doc__[] =
1750"fork() -> pid\n\
1751Fork a child process.\n\
1752\n\
1753Return 0 to child process and PID of child to parent process.";
1754
Barry Warsaw53699e91996-12-10 23:23:01 +00001755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001756posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001757{
1758 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001759 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001760 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001761 pid = fork();
1762 if (pid == -1)
1763 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001764 if (pid == 0)
1765 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001766 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001767}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001768#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001769
Fred Drake8cef4cf2000-06-28 16:40:38 +00001770#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1771#ifdef HAVE_PTY_H
1772#include <pty.h>
1773#else
1774#ifdef HAVE_LIBUTIL_H
1775#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001776#endif /* HAVE_LIBUTIL_H */
1777#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001778#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001779
Thomas Wouters70c21a12000-07-14 14:28:33 +00001780#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001781static char posix_openpty__doc__[] =
1782"openpty() -> (master_fd, slave_fd)\n\
1783Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1784
1785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001786posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001787{
1788 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001789#ifndef HAVE_OPENPTY
1790 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001791#endif
1792
Fred Drake8cef4cf2000-06-28 16:40:38 +00001793 if (!PyArg_ParseTuple(args, ":openpty"))
1794 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001795
1796#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001797 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1798 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001799#else
1800 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1801 if (slave_name == NULL)
1802 return posix_error();
1803
1804 slave_fd = open(slave_name, O_RDWR);
1805 if (slave_fd < 0)
1806 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001807#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001808
Fred Drake8cef4cf2000-06-28 16:40:38 +00001809 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001810
Fred Drake8cef4cf2000-06-28 16:40:38 +00001811}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001812#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001813
1814#ifdef HAVE_FORKPTY
1815static char posix_forkpty__doc__[] =
1816"forkpty() -> (pid, master_fd)\n\
1817Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1818Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1819To both, return fd of newly opened pseudo-terminal.\n";
1820
1821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001822posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001823{
1824 int master_fd, pid;
1825
1826 if (!PyArg_ParseTuple(args, ":forkpty"))
1827 return NULL;
1828 pid = forkpty(&master_fd, NULL, NULL, NULL);
1829 if (pid == -1)
1830 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001831 if (pid == 0)
1832 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001833 return Py_BuildValue("(ii)", pid, master_fd);
1834}
1835#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001836
Guido van Rossumad0ee831995-03-01 10:34:45 +00001837#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001838static char posix_getegid__doc__[] =
1839"getegid() -> egid\n\
1840Return the current process's effective group id.";
1841
Barry Warsaw53699e91996-12-10 23:23:01 +00001842static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001843posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001844{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001845 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001846 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001847 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001848}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001849#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001851
Guido van Rossumad0ee831995-03-01 10:34:45 +00001852#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001853static char posix_geteuid__doc__[] =
1854"geteuid() -> euid\n\
1855Return the current process's effective user id.";
1856
Barry Warsaw53699e91996-12-10 23:23:01 +00001857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001858posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001859{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001860 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001861 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001862 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001863}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001864#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001865
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001866
Guido van Rossumad0ee831995-03-01 10:34:45 +00001867#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001868static char posix_getgid__doc__[] =
1869"getgid() -> gid\n\
1870Return the current process's group id.";
1871
Barry Warsaw53699e91996-12-10 23:23:01 +00001872static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001873posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001874{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001875 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001876 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001877 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001878}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001879#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001880
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001881
1882static char posix_getpid__doc__[] =
1883"getpid() -> pid\n\
1884Return the current process id";
1885
Barry Warsaw53699e91996-12-10 23:23:01 +00001886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001887posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001888{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001889 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001890 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001891 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001892}
1893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001894
Fred Drakec9680921999-12-13 16:37:25 +00001895#ifdef HAVE_GETGROUPS
1896static char posix_getgroups__doc__[] = "\
1897getgroups() -> list of group IDs\n\
1898Return list of supplemental group IDs for the process.";
1899
1900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001901posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001902{
1903 PyObject *result = NULL;
1904
1905 if (PyArg_ParseTuple(args, ":getgroups")) {
1906#ifdef NGROUPS_MAX
1907#define MAX_GROUPS NGROUPS_MAX
1908#else
1909 /* defined to be 16 on Solaris7, so this should be a small number */
1910#define MAX_GROUPS 64
1911#endif
1912 gid_t grouplist[MAX_GROUPS];
1913 int n;
1914
1915 n = getgroups(MAX_GROUPS, grouplist);
1916 if (n < 0)
1917 posix_error();
1918 else {
1919 result = PyList_New(n);
1920 if (result != NULL) {
1921 PyObject *o;
1922 int i;
1923 for (i = 0; i < n; ++i) {
1924 o = PyInt_FromLong((long)grouplist[i]);
1925 if (o == NULL) {
1926 Py_DECREF(result);
1927 result = NULL;
1928 break;
1929 }
1930 PyList_SET_ITEM(result, i, o);
1931 }
1932 }
1933 }
1934 }
1935 return result;
1936}
1937#endif
1938
Guido van Rossumb6775db1994-08-01 11:34:53 +00001939#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001940static char posix_getpgrp__doc__[] =
1941"getpgrp() -> pgrp\n\
1942Return the current process group id.";
1943
Barry Warsaw53699e91996-12-10 23:23:01 +00001944static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001945posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001946{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001947 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001948 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001949#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001950 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001951#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001952 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001953#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001954}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001955#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001956
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001957
Guido van Rossumb6775db1994-08-01 11:34:53 +00001958#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001959static char posix_setpgrp__doc__[] =
1960"setpgrp() -> None\n\
1961Make this process a session leader.";
1962
Barry Warsaw53699e91996-12-10 23:23:01 +00001963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001964posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001965{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001966 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001967 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001968#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001969 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001970#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001971 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001972#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001973 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001974 Py_INCREF(Py_None);
1975 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001976}
1977
Guido van Rossumb6775db1994-08-01 11:34:53 +00001978#endif /* HAVE_SETPGRP */
1979
Guido van Rossumad0ee831995-03-01 10:34:45 +00001980#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001981static char posix_getppid__doc__[] =
1982"getppid() -> ppid\n\
1983Return the parent's process id.";
1984
Barry Warsaw53699e91996-12-10 23:23:01 +00001985static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001986posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001987{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001988 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001989 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001990 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001991}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001992#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001994
Fred Drake12c6e2d1999-12-14 21:25:03 +00001995#ifdef HAVE_GETLOGIN
1996static char posix_getlogin__doc__[] = "\
1997getlogin() -> string\n\
1998Return the actual login name.";
1999
2000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002001posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002002{
2003 PyObject *result = NULL;
2004
2005 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002006 char *name;
2007 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002008
Fred Drakea30680b2000-12-06 21:24:28 +00002009 errno = 0;
2010 name = getlogin();
2011 if (name == NULL) {
2012 if (errno)
2013 posix_error();
2014 else
2015 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002016 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002017 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002018 else
2019 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002020 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002021 }
2022 return result;
2023}
2024#endif
2025
Guido van Rossumad0ee831995-03-01 10:34:45 +00002026#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002027static char posix_getuid__doc__[] =
2028"getuid() -> uid\n\
2029Return the current process's user id.";
2030
Barry Warsaw53699e91996-12-10 23:23:01 +00002031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002032posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002033{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002034 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002035 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002036 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002037}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002038#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002039
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002040
Guido van Rossumad0ee831995-03-01 10:34:45 +00002041#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002042static char posix_kill__doc__[] =
2043"kill(pid, sig) -> None\n\
2044Kill a process with a signal.";
2045
Barry Warsaw53699e91996-12-10 23:23:01 +00002046static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002047posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002048{
2049 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002050 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002051 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002052#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002053 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2054 APIRET rc;
2055 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002056 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002057
2058 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2059 APIRET rc;
2060 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002061 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002062
2063 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002064 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002065#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002066 if (kill(pid, sig) == -1)
2067 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002068#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002069 Py_INCREF(Py_None);
2070 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002071}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002072#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002073
Guido van Rossumc0125471996-06-28 18:55:32 +00002074#ifdef HAVE_PLOCK
2075
2076#ifdef HAVE_SYS_LOCK_H
2077#include <sys/lock.h>
2078#endif
2079
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002080static char posix_plock__doc__[] =
2081"plock(op) -> None\n\
2082Lock program segments into memory.";
2083
Barry Warsaw53699e91996-12-10 23:23:01 +00002084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002085posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002086{
2087 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002088 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002089 return NULL;
2090 if (plock(op) == -1)
2091 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002092 Py_INCREF(Py_None);
2093 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002094}
2095#endif
2096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002097
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002098#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002099static char posix_popen__doc__[] =
2100"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2101Open a pipe to/from a command returning a file object.";
2102
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002103#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002104static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002105async_system(const char *command)
2106{
2107 char *p, errormsg[256], args[1024];
2108 RESULTCODES rcodes;
2109 APIRET rc;
2110 char *shell = getenv("COMSPEC");
2111 if (!shell)
2112 shell = "cmd";
2113
2114 strcpy(args, shell);
2115 p = &args[ strlen(args)+1 ];
2116 strcpy(p, "/c ");
2117 strcat(p, command);
2118 p += strlen(p) + 1;
2119 *p = '\0';
2120
2121 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002122 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002123 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002124 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002125 &rcodes, shell);
2126 return rc;
2127}
2128
Guido van Rossumd48f2521997-12-05 22:19:34 +00002129static FILE *
2130popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002131{
2132 HFILE rhan, whan;
2133 FILE *retfd = NULL;
2134 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2135
Guido van Rossumd48f2521997-12-05 22:19:34 +00002136 if (rc != NO_ERROR) {
2137 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002138 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002139 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002140
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002141 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2142 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002143
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002144 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2145 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002146
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002147 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2148 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002149
2150 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002151 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002152 }
2153
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002154 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2155 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002156
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002157 close(oldfd); /* And Close Saved STDOUT Handle */
2158 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002159
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002160 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2161 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002162
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002163 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2164 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002165
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002166 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2167 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002168
2169 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002170 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002171 }
2172
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002173 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2174 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002175
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002176 close(oldfd); /* And Close Saved STDIN Handle */
2177 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002178
Guido van Rossumd48f2521997-12-05 22:19:34 +00002179 } else {
2180 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002181 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002182 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002183}
2184
2185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002186posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002187{
2188 char *name;
2189 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002190 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002191 FILE *fp;
2192 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002193 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002194 return NULL;
2195 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002196 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002197 Py_END_ALLOW_THREADS
2198 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002199 return os2_error(err);
2200
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002201 f = PyFile_FromFile(fp, name, mode, fclose);
2202 if (f != NULL)
2203 PyFile_SetBufSize(f, bufsize);
2204 return f;
2205}
2206
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002207#elif defined(MS_WIN32)
2208
2209/*
2210 * Portable 'popen' replacement for Win32.
2211 *
2212 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2213 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002214 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002215 */
2216
2217#include <malloc.h>
2218#include <io.h>
2219#include <fcntl.h>
2220
2221/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2222#define POPEN_1 1
2223#define POPEN_2 2
2224#define POPEN_3 3
2225#define POPEN_4 4
2226
2227static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002228static int _PyPclose(FILE *file);
2229
2230/*
2231 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002232 * for use when retrieving the process exit code. See _PyPclose() below
2233 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002234 */
2235static PyObject *_PyPopenProcs = NULL;
2236
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002237
2238/* popen that works from a GUI.
2239 *
2240 * The result of this function is a pipe (file) connected to the
2241 * processes stdin or stdout, depending on the requested mode.
2242 */
2243
2244static PyObject *
2245posix_popen(PyObject *self, PyObject *args)
2246{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002247 PyObject *f, *s;
2248 int tm = 0;
2249
2250 char *cmdstring;
2251 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002252 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002253 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002254 return NULL;
2255
2256 s = PyTuple_New(0);
2257
2258 if (*mode == 'r')
2259 tm = _O_RDONLY;
2260 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002261 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002262 return NULL;
2263 } else
2264 tm = _O_WRONLY;
2265
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002266 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002267 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002268 return NULL;
2269 }
2270
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002271 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002272 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002273 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002274 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002275 else
2276 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2277
2278 return f;
2279}
2280
2281/* Variation on win32pipe.popen
2282 *
2283 * The result of this function is a pipe (file) connected to the
2284 * process's stdin, and a pipe connected to the process's stdout.
2285 */
2286
2287static PyObject *
2288win32_popen2(PyObject *self, PyObject *args)
2289{
2290 PyObject *f;
2291 int tm=0;
2292
2293 char *cmdstring;
2294 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002295 int bufsize = -1;
2296 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002297 return NULL;
2298
2299 if (*mode == 't')
2300 tm = _O_TEXT;
2301 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002302 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002303 return NULL;
2304 } else
2305 tm = _O_BINARY;
2306
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002307 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002308 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002309 return NULL;
2310 }
2311
2312 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002313
2314 return f;
2315}
2316
2317/*
2318 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002319 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002320 * The result of this function is 3 pipes - the process's stdin,
2321 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002322 */
2323
2324static PyObject *
2325win32_popen3(PyObject *self, PyObject *args)
2326{
2327 PyObject *f;
2328 int tm = 0;
2329
2330 char *cmdstring;
2331 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002332 int bufsize = -1;
2333 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002334 return NULL;
2335
2336 if (*mode == 't')
2337 tm = _O_TEXT;
2338 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002339 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002340 return NULL;
2341 } else
2342 tm = _O_BINARY;
2343
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002344 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002345 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002346 return NULL;
2347 }
2348
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002349 f = _PyPopen(cmdstring, tm, POPEN_3);
2350
2351 return f;
2352}
2353
2354/*
2355 * Variation on win32pipe.popen
2356 *
2357 * The result of this function is 2 pipes - the processes stdin,
2358 * and stdout+stderr combined as a single pipe.
2359 */
2360
2361static PyObject *
2362win32_popen4(PyObject *self, PyObject *args)
2363{
2364 PyObject *f;
2365 int tm = 0;
2366
2367 char *cmdstring;
2368 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002369 int bufsize = -1;
2370 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002371 return NULL;
2372
2373 if (*mode == 't')
2374 tm = _O_TEXT;
2375 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002376 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002377 return NULL;
2378 } else
2379 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002380
2381 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002382 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002383 return NULL;
2384 }
2385
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002386 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002387
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002388 return f;
2389}
2390
Mark Hammond08501372001-01-31 07:30:29 +00002391static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002392_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002393 HANDLE hStdin,
2394 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002395 HANDLE hStderr,
2396 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002397{
2398 PROCESS_INFORMATION piProcInfo;
2399 STARTUPINFO siStartInfo;
2400 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002401 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002402 int i;
2403 int x;
2404
2405 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002406 char *comshell;
2407
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002408 s1 = (char *)_alloca(i);
2409 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2410 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002411
2412 /* Explicitly check if we are using COMMAND.COM. If we are
2413 * then use the w9xpopen hack.
2414 */
2415 comshell = s1 + x;
2416 while (comshell >= s1 && *comshell != '\\')
2417 --comshell;
2418 ++comshell;
2419
2420 if (GetVersion() < 0x80000000 &&
2421 _stricmp(comshell, "command.com") != 0) {
2422 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002423 x = i + strlen(s3) + strlen(cmdstring) + 1;
2424 s2 = (char *)_alloca(x);
2425 ZeroMemory(s2, x);
2426 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2427 }
2428 else {
2429 /*
Tim Peters402d5982001-08-27 06:37:48 +00002430 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2431 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002432 */
Mark Hammond08501372001-01-31 07:30:29 +00002433 char modulepath[_MAX_PATH];
2434 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002435 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2436 for (i = x = 0; modulepath[i]; i++)
2437 if (modulepath[i] == '\\')
2438 x = i+1;
2439 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002440 /* Create the full-name to w9xpopen, so we can test it exists */
2441 strncat(modulepath,
2442 szConsoleSpawn,
2443 (sizeof(modulepath)/sizeof(modulepath[0]))
2444 -strlen(modulepath));
2445 if (stat(modulepath, &statinfo) != 0) {
2446 /* Eeek - file-not-found - possibly an embedding
2447 situation - see if we can locate it in sys.prefix
2448 */
2449 strncpy(modulepath,
2450 Py_GetExecPrefix(),
2451 sizeof(modulepath)/sizeof(modulepath[0]));
2452 if (modulepath[strlen(modulepath)-1] != '\\')
2453 strcat(modulepath, "\\");
2454 strncat(modulepath,
2455 szConsoleSpawn,
2456 (sizeof(modulepath)/sizeof(modulepath[0]))
2457 -strlen(modulepath));
2458 /* No where else to look - raise an easily identifiable
2459 error, rather than leaving Windows to report
2460 "file not found" - as the user is probably blissfully
2461 unaware this shim EXE is used, and it will confuse them.
2462 (well, it confused me for a while ;-)
2463 */
2464 if (stat(modulepath, &statinfo) != 0) {
2465 PyErr_Format(PyExc_RuntimeError,
2466 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002467 "for popen to work with your shell "
2468 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002469 szConsoleSpawn);
2470 return FALSE;
2471 }
2472 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002473 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2474 strlen(modulepath) +
2475 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002476
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002477 s2 = (char *)_alloca(x);
2478 ZeroMemory(s2, x);
2479 sprintf(
2480 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002481 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002482 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002483 s1,
2484 s3,
2485 cmdstring);
2486 }
2487 }
2488
2489 /* Could be an else here to try cmd.exe / command.com in the path
2490 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002491 else {
Tim Peters402d5982001-08-27 06:37:48 +00002492 PyErr_SetString(PyExc_RuntimeError,
2493 "Cannot locate a COMSPEC environment variable to "
2494 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002495 return FALSE;
2496 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002497
2498 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2499 siStartInfo.cb = sizeof(STARTUPINFO);
2500 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2501 siStartInfo.hStdInput = hStdin;
2502 siStartInfo.hStdOutput = hStdout;
2503 siStartInfo.hStdError = hStderr;
2504 siStartInfo.wShowWindow = SW_HIDE;
2505
2506 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002507 s2,
2508 NULL,
2509 NULL,
2510 TRUE,
2511 CREATE_NEW_CONSOLE,
2512 NULL,
2513 NULL,
2514 &siStartInfo,
2515 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002516 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002517 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002518
Mark Hammondb37a3732000-08-14 04:47:33 +00002519 /* Return process handle */
2520 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002521 return TRUE;
2522 }
Tim Peters402d5982001-08-27 06:37:48 +00002523 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002524 return FALSE;
2525}
2526
2527/* The following code is based off of KB: Q190351 */
2528
2529static PyObject *
2530_PyPopen(char *cmdstring, int mode, int n)
2531{
2532 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2533 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002534 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002535
2536 SECURITY_ATTRIBUTES saAttr;
2537 BOOL fSuccess;
2538 int fd1, fd2, fd3;
2539 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002540 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002541 PyObject *f;
2542
2543 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2544 saAttr.bInheritHandle = TRUE;
2545 saAttr.lpSecurityDescriptor = NULL;
2546
2547 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2548 return win32_error("CreatePipe", NULL);
2549
2550 /* Create new output read handle and the input write handle. Set
2551 * the inheritance properties to FALSE. Otherwise, the child inherits
2552 * the these handles; resulting in non-closeable handles to the pipes
2553 * being created. */
2554 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002555 GetCurrentProcess(), &hChildStdinWrDup, 0,
2556 FALSE,
2557 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002558 if (!fSuccess)
2559 return win32_error("DuplicateHandle", NULL);
2560
2561 /* Close the inheritable version of ChildStdin
2562 that we're using. */
2563 CloseHandle(hChildStdinWr);
2564
2565 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2566 return win32_error("CreatePipe", NULL);
2567
2568 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002569 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2570 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002571 if (!fSuccess)
2572 return win32_error("DuplicateHandle", NULL);
2573
2574 /* Close the inheritable version of ChildStdout
2575 that we're using. */
2576 CloseHandle(hChildStdoutRd);
2577
2578 if (n != POPEN_4) {
2579 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2580 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002581 fSuccess = DuplicateHandle(GetCurrentProcess(),
2582 hChildStderrRd,
2583 GetCurrentProcess(),
2584 &hChildStderrRdDup, 0,
2585 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002586 if (!fSuccess)
2587 return win32_error("DuplicateHandle", NULL);
2588 /* Close the inheritable version of ChildStdErr that we're using. */
2589 CloseHandle(hChildStderrRd);
2590 }
2591
2592 switch (n) {
2593 case POPEN_1:
2594 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2595 case _O_WRONLY | _O_TEXT:
2596 /* Case for writing to child Stdin in text mode. */
2597 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2598 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002599 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002600 PyFile_SetBufSize(f, 0);
2601 /* We don't care about these pipes anymore, so close them. */
2602 CloseHandle(hChildStdoutRdDup);
2603 CloseHandle(hChildStderrRdDup);
2604 break;
2605
2606 case _O_RDONLY | _O_TEXT:
2607 /* Case for reading from child Stdout in text mode. */
2608 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2609 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002610 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002611 PyFile_SetBufSize(f, 0);
2612 /* We don't care about these pipes anymore, so close them. */
2613 CloseHandle(hChildStdinWrDup);
2614 CloseHandle(hChildStderrRdDup);
2615 break;
2616
2617 case _O_RDONLY | _O_BINARY:
2618 /* Case for readinig from child Stdout in binary mode. */
2619 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2620 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002621 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002622 PyFile_SetBufSize(f, 0);
2623 /* We don't care about these pipes anymore, so close them. */
2624 CloseHandle(hChildStdinWrDup);
2625 CloseHandle(hChildStderrRdDup);
2626 break;
2627
2628 case _O_WRONLY | _O_BINARY:
2629 /* Case for writing to child Stdin in binary mode. */
2630 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2631 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002632 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002633 PyFile_SetBufSize(f, 0);
2634 /* We don't care about these pipes anymore, so close them. */
2635 CloseHandle(hChildStdoutRdDup);
2636 CloseHandle(hChildStderrRdDup);
2637 break;
2638 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002639 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002640 break;
2641
2642 case POPEN_2:
2643 case POPEN_4:
2644 {
2645 char *m1, *m2;
2646 PyObject *p1, *p2;
2647
2648 if (mode && _O_TEXT) {
2649 m1 = "r";
2650 m2 = "w";
2651 } else {
2652 m1 = "rb";
2653 m2 = "wb";
2654 }
2655
2656 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2657 f1 = _fdopen(fd1, m2);
2658 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2659 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002660 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002661 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002662 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002663 PyFile_SetBufSize(p2, 0);
2664
2665 if (n != 4)
2666 CloseHandle(hChildStderrRdDup);
2667
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002668 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002669 Py_XDECREF(p1);
2670 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002671 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002672 break;
2673 }
2674
2675 case POPEN_3:
2676 {
2677 char *m1, *m2;
2678 PyObject *p1, *p2, *p3;
2679
2680 if (mode && _O_TEXT) {
2681 m1 = "r";
2682 m2 = "w";
2683 } else {
2684 m1 = "rb";
2685 m2 = "wb";
2686 }
2687
2688 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2689 f1 = _fdopen(fd1, m2);
2690 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2691 f2 = _fdopen(fd2, m1);
2692 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2693 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002694 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002695 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2696 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002697 PyFile_SetBufSize(p1, 0);
2698 PyFile_SetBufSize(p2, 0);
2699 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002700 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002701 Py_XDECREF(p1);
2702 Py_XDECREF(p2);
2703 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002704 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002705 break;
2706 }
2707 }
2708
2709 if (n == POPEN_4) {
2710 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002711 hChildStdinRd,
2712 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002713 hChildStdoutWr,
2714 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002715 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002716 }
2717 else {
2718 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002719 hChildStdinRd,
2720 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002721 hChildStderrWr,
2722 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002723 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002724 }
2725
Mark Hammondb37a3732000-08-14 04:47:33 +00002726 /*
2727 * Insert the files we've created into the process dictionary
2728 * all referencing the list with the process handle and the
2729 * initial number of files (see description below in _PyPclose).
2730 * Since if _PyPclose later tried to wait on a process when all
2731 * handles weren't closed, it could create a deadlock with the
2732 * child, we spend some energy here to try to ensure that we
2733 * either insert all file handles into the dictionary or none
2734 * at all. It's a little clumsy with the various popen modes
2735 * and variable number of files involved.
2736 */
2737 if (!_PyPopenProcs) {
2738 _PyPopenProcs = PyDict_New();
2739 }
2740
2741 if (_PyPopenProcs) {
2742 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2743 int ins_rc[3];
2744
2745 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2746 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2747
2748 procObj = PyList_New(2);
2749 hProcessObj = PyLong_FromVoidPtr(hProcess);
2750 intObj = PyInt_FromLong(file_count);
2751
2752 if (procObj && hProcessObj && intObj) {
2753 PyList_SetItem(procObj,0,hProcessObj);
2754 PyList_SetItem(procObj,1,intObj);
2755
2756 fileObj[0] = PyLong_FromVoidPtr(f1);
2757 if (fileObj[0]) {
2758 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2759 fileObj[0],
2760 procObj);
2761 }
2762 if (file_count >= 2) {
2763 fileObj[1] = PyLong_FromVoidPtr(f2);
2764 if (fileObj[1]) {
2765 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2766 fileObj[1],
2767 procObj);
2768 }
2769 }
2770 if (file_count >= 3) {
2771 fileObj[2] = PyLong_FromVoidPtr(f3);
2772 if (fileObj[2]) {
2773 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2774 fileObj[2],
2775 procObj);
2776 }
2777 }
2778
2779 if (ins_rc[0] < 0 || !fileObj[0] ||
2780 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2781 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2782 /* Something failed - remove any dictionary
2783 * entries that did make it.
2784 */
2785 if (!ins_rc[0] && fileObj[0]) {
2786 PyDict_DelItem(_PyPopenProcs,
2787 fileObj[0]);
2788 }
2789 if (!ins_rc[1] && fileObj[1]) {
2790 PyDict_DelItem(_PyPopenProcs,
2791 fileObj[1]);
2792 }
2793 if (!ins_rc[2] && fileObj[2]) {
2794 PyDict_DelItem(_PyPopenProcs,
2795 fileObj[2]);
2796 }
2797 }
2798 }
2799
2800 /*
2801 * Clean up our localized references for the dictionary keys
2802 * and value since PyDict_SetItem will Py_INCREF any copies
2803 * that got placed in the dictionary.
2804 */
2805 Py_XDECREF(procObj);
2806 Py_XDECREF(fileObj[0]);
2807 Py_XDECREF(fileObj[1]);
2808 Py_XDECREF(fileObj[2]);
2809 }
2810
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002811 /* Child is launched. Close the parents copy of those pipe
2812 * handles that only the child should have open. You need to
2813 * make sure that no handles to the write end of the output pipe
2814 * are maintained in this process or else the pipe will not close
2815 * when the child process exits and the ReadFile will hang. */
2816
2817 if (!CloseHandle(hChildStdinRd))
2818 return win32_error("CloseHandle", NULL);
2819
2820 if (!CloseHandle(hChildStdoutWr))
2821 return win32_error("CloseHandle", NULL);
2822
2823 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2824 return win32_error("CloseHandle", NULL);
2825
2826 return f;
2827}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002828
2829/*
2830 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2831 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002832 *
2833 * This function uses the _PyPopenProcs dictionary in order to map the
2834 * input file pointer to information about the process that was
2835 * originally created by the popen* call that created the file pointer.
2836 * The dictionary uses the file pointer as a key (with one entry
2837 * inserted for each file returned by the original popen* call) and a
2838 * single list object as the value for all files from a single call.
2839 * The list object contains the Win32 process handle at [0], and a file
2840 * count at [1], which is initialized to the total number of file
2841 * handles using that list.
2842 *
2843 * This function closes whichever handle it is passed, and decrements
2844 * the file count in the dictionary for the process handle pointed to
2845 * by this file. On the last close (when the file count reaches zero),
2846 * this function will wait for the child process and then return its
2847 * exit code as the result of the close() operation. This permits the
2848 * files to be closed in any order - it is always the close() of the
2849 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002850 */
Tim Peters736aa322000-09-01 06:51:24 +00002851
2852 /* RED_FLAG 31-Aug-2000 Tim
2853 * This is always called (today!) between a pair of
2854 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2855 * macros. So the thread running this has no valid thread state, as
2856 * far as Python is concerned. However, this calls some Python API
2857 * functions that cannot be called safely without a valid thread
2858 * state, in particular PyDict_GetItem.
2859 * As a temporary hack (although it may last for years ...), we
2860 * *rely* on not having a valid thread state in this function, in
2861 * order to create our own "from scratch".
2862 * This will deadlock if _PyPclose is ever called by a thread
2863 * holding the global lock.
2864 */
2865
Fredrik Lundh56055a42000-07-23 19:47:12 +00002866static int _PyPclose(FILE *file)
2867{
Fredrik Lundh20318932000-07-26 17:29:12 +00002868 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002869 DWORD exit_code;
2870 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002871 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2872 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002873#ifdef WITH_THREAD
2874 PyInterpreterState* pInterpreterState;
2875 PyThreadState* pThreadState;
2876#endif
2877
Fredrik Lundh20318932000-07-26 17:29:12 +00002878 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002879 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002880 */
2881 result = fclose(file);
2882
Tim Peters736aa322000-09-01 06:51:24 +00002883#ifdef WITH_THREAD
2884 /* Bootstrap a valid thread state into existence. */
2885 pInterpreterState = PyInterpreterState_New();
2886 if (!pInterpreterState) {
2887 /* Well, we're hosed now! We don't have a thread
2888 * state, so can't call a nice error routine, or raise
2889 * an exception. Just die.
2890 */
2891 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002892 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002893 return -1; /* unreachable */
2894 }
2895 pThreadState = PyThreadState_New(pInterpreterState);
2896 if (!pThreadState) {
2897 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002898 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002899 return -1; /* unreachable */
2900 }
2901 /* Grab the global lock. Note that this will deadlock if the
2902 * current thread already has the lock! (see RED_FLAG comments
2903 * before this function)
2904 */
2905 PyEval_RestoreThread(pThreadState);
2906#endif
2907
Fredrik Lundh56055a42000-07-23 19:47:12 +00002908 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002909 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2910 (procObj = PyDict_GetItem(_PyPopenProcs,
2911 fileObj)) != NULL &&
2912 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2913 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2914
2915 hProcess = PyLong_AsVoidPtr(hProcessObj);
2916 file_count = PyInt_AsLong(intObj);
2917
2918 if (file_count > 1) {
2919 /* Still other files referencing process */
2920 file_count--;
2921 PyList_SetItem(procObj,1,
2922 PyInt_FromLong(file_count));
2923 } else {
2924 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002925 if (result != EOF &&
2926 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2927 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002928 /* Possible truncation here in 16-bit environments, but
2929 * real exit codes are just the lower byte in any event.
2930 */
2931 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002932 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002933 /* Indicate failure - this will cause the file object
2934 * to raise an I/O error and translate the last Win32
2935 * error code from errno. We do have a problem with
2936 * last errors that overlap the normal errno table,
2937 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002938 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002939 if (result != EOF) {
2940 /* If the error wasn't from the fclose(), then
2941 * set errno for the file object error handling.
2942 */
2943 errno = GetLastError();
2944 }
2945 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002946 }
2947
2948 /* Free up the native handle at this point */
2949 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002950 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002951
Mark Hammondb37a3732000-08-14 04:47:33 +00002952 /* Remove this file pointer from dictionary */
2953 PyDict_DelItem(_PyPopenProcs, fileObj);
2954
2955 if (PyDict_Size(_PyPopenProcs) == 0) {
2956 Py_DECREF(_PyPopenProcs);
2957 _PyPopenProcs = NULL;
2958 }
2959
2960 } /* if object retrieval ok */
2961
2962 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002963 } /* if _PyPopenProcs */
2964
Tim Peters736aa322000-09-01 06:51:24 +00002965#ifdef WITH_THREAD
2966 /* Tear down the thread & interpreter states.
2967 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002968 * call the thread clear & delete functions, and indeed insist on
2969 * doing that themselves. The lock must be held during the clear, but
2970 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002971 */
2972 PyInterpreterState_Clear(pInterpreterState);
2973 PyEval_ReleaseThread(pThreadState);
2974 PyInterpreterState_Delete(pInterpreterState);
2975#endif
2976
Fredrik Lundh56055a42000-07-23 19:47:12 +00002977 return result;
2978}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002979
2980#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002982posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002983{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002984 char *name;
2985 char *mode = "r";
2986 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002987 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002988 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002989 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002990 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002991 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002992 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002993 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002994 if (fp == NULL)
2995 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002996 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002997 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002998 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002999 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003000}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003001#endif
3002
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003003#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003004
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003005
Guido van Rossumb6775db1994-08-01 11:34:53 +00003006#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003007static char posix_setuid__doc__[] =
3008"setuid(uid) -> None\n\
3009Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003010static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003011posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003012{
3013 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003014 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003015 return NULL;
3016 if (setuid(uid) < 0)
3017 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003018 Py_INCREF(Py_None);
3019 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003020}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003021#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003022
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003023
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003024#ifdef HAVE_SETEUID
3025static char posix_seteuid__doc__[] =
3026"seteuid(uid) -> None\n\
3027Set the current process's effective user id.";
3028static PyObject *
3029posix_seteuid (PyObject *self, PyObject *args)
3030{
3031 int euid;
3032 if (!PyArg_ParseTuple(args, "i", &euid)) {
3033 return NULL;
3034 } else if (seteuid(euid) < 0) {
3035 return posix_error();
3036 } else {
3037 Py_INCREF(Py_None);
3038 return Py_None;
3039 }
3040}
3041#endif /* HAVE_SETEUID */
3042
3043#ifdef HAVE_SETEGID
3044static char posix_setegid__doc__[] =
3045"setegid(gid) -> None\n\
3046Set the current process's effective group id.";
3047static PyObject *
3048posix_setegid (PyObject *self, PyObject *args)
3049{
3050 int egid;
3051 if (!PyArg_ParseTuple(args, "i", &egid)) {
3052 return NULL;
3053 } else if (setegid(egid) < 0) {
3054 return posix_error();
3055 } else {
3056 Py_INCREF(Py_None);
3057 return Py_None;
3058 }
3059}
3060#endif /* HAVE_SETEGID */
3061
3062#ifdef HAVE_SETREUID
3063static char posix_setreuid__doc__[] =
3064"seteuid(ruid, euid) -> None\n\
3065Set the current process's real and effective user ids.";
3066static PyObject *
3067posix_setreuid (PyObject *self, PyObject *args)
3068{
3069 int ruid, euid;
3070 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3071 return NULL;
3072 } else if (setreuid(ruid, euid) < 0) {
3073 return posix_error();
3074 } else {
3075 Py_INCREF(Py_None);
3076 return Py_None;
3077 }
3078}
3079#endif /* HAVE_SETREUID */
3080
3081#ifdef HAVE_SETREGID
3082static char posix_setregid__doc__[] =
3083"setegid(rgid, egid) -> None\n\
3084Set the current process's real and effective group ids.";
3085static PyObject *
3086posix_setregid (PyObject *self, PyObject *args)
3087{
3088 int rgid, egid;
3089 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3090 return NULL;
3091 } else if (setregid(rgid, egid) < 0) {
3092 return posix_error();
3093 } else {
3094 Py_INCREF(Py_None);
3095 return Py_None;
3096 }
3097}
3098#endif /* HAVE_SETREGID */
3099
Guido van Rossumb6775db1994-08-01 11:34:53 +00003100#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003101static char posix_setgid__doc__[] =
3102"setgid(gid) -> None\n\
3103Set the current process's group id.";
3104
Barry Warsaw53699e91996-12-10 23:23:01 +00003105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003106posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003107{
3108 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003109 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003110 return NULL;
3111 if (setgid(gid) < 0)
3112 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003113 Py_INCREF(Py_None);
3114 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003115}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003116#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003118
Guido van Rossumb6775db1994-08-01 11:34:53 +00003119#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003120static char posix_waitpid__doc__[] =
3121"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003122Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003123
Barry Warsaw53699e91996-12-10 23:23:01 +00003124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003125posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003126{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003127 int pid, options;
3128#ifdef UNION_WAIT
3129 union wait status;
3130#define status_i (status.w_status)
3131#else
3132 int status;
3133#define status_i status
3134#endif
3135 status_i = 0;
3136
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003137 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003138 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003139 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003140#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003141 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003142#else
3143 pid = waitpid(pid, &status, options);
3144#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003145 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003146 if (pid == -1)
3147 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003148 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003149 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003150}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003151#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003153
Guido van Rossumad0ee831995-03-01 10:34:45 +00003154#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155static char posix_wait__doc__[] =
3156"wait() -> (pid, status)\n\
3157Wait for completion of a child process.";
3158
Barry Warsaw53699e91996-12-10 23:23:01 +00003159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003160posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003161{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003162 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003163#ifdef UNION_WAIT
3164 union wait status;
3165#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003166#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003167 int status;
3168#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003169#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003170 if (!PyArg_ParseTuple(args, ":wait"))
3171 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003172 status_i = 0;
3173 Py_BEGIN_ALLOW_THREADS
3174 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003175 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003176 if (pid == -1)
3177 return posix_error();
3178 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003179 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003180#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003181}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003182#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003183
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003184
3185static char posix_lstat__doc__[] =
3186"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3187Like stat(path), but do not follow symbolic links.";
3188
Barry Warsaw53699e91996-12-10 23:23:01 +00003189static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003190posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003191{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003192#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003193 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003194#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003195 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003196#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003197}
3198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003199
Guido van Rossumb6775db1994-08-01 11:34:53 +00003200#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003201static char posix_readlink__doc__[] =
3202"readlink(path) -> path\n\
3203Return a string representing the path to which the symbolic link points.";
3204
Barry Warsaw53699e91996-12-10 23:23:01 +00003205static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003206posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003207{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003208 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003209 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003210 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003211 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003212 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003213 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003214 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003215 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003216 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003217 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003218 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003219}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003220#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003222
Guido van Rossumb6775db1994-08-01 11:34:53 +00003223#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003224static char posix_symlink__doc__[] =
3225"symlink(src, dst) -> None\n\
3226Create a symbolic link.";
3227
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003229posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003230{
Mark Hammondef8b6542001-05-13 08:04:26 +00003231 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003232}
3233#endif /* HAVE_SYMLINK */
3234
3235
3236#ifdef HAVE_TIMES
3237#ifndef HZ
3238#define HZ 60 /* Universal constant :-) */
3239#endif /* HZ */
3240
Guido van Rossumd48f2521997-12-05 22:19:34 +00003241#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3242static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003243system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003244{
3245 ULONG value = 0;
3246
3247 Py_BEGIN_ALLOW_THREADS
3248 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3249 Py_END_ALLOW_THREADS
3250
3251 return value;
3252}
3253
3254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003255posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003256{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003257 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003258 return NULL;
3259
3260 /* Currently Only Uptime is Provided -- Others Later */
3261 return Py_BuildValue("ddddd",
3262 (double)0 /* t.tms_utime / HZ */,
3263 (double)0 /* t.tms_stime / HZ */,
3264 (double)0 /* t.tms_cutime / HZ */,
3265 (double)0 /* t.tms_cstime / HZ */,
3266 (double)system_uptime() / 1000);
3267}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003268#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003270posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003271{
3272 struct tms t;
3273 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003274 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003275 return NULL;
3276 errno = 0;
3277 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003278 if (c == (clock_t) -1)
3279 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003280 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003281 (double)t.tms_utime / HZ,
3282 (double)t.tms_stime / HZ,
3283 (double)t.tms_cutime / HZ,
3284 (double)t.tms_cstime / HZ,
3285 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003286}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003287#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003288#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003289
3290
Guido van Rossum87755a21996-09-07 00:59:43 +00003291#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003292#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003294posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003295{
3296 FILETIME create, exit, kernel, user;
3297 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003298 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003299 return NULL;
3300 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003301 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3302 /* The fields of a FILETIME structure are the hi and lo part
3303 of a 64-bit value expressed in 100 nanosecond units.
3304 1e7 is one second in such units; 1e-7 the inverse.
3305 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3306 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003307 return Py_BuildValue(
3308 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003309 (double)(kernel.dwHighDateTime*429.4967296 +
3310 kernel.dwLowDateTime*1e-7),
3311 (double)(user.dwHighDateTime*429.4967296 +
3312 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003313 (double)0,
3314 (double)0,
3315 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003316}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003317#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003318
3319#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003320static char posix_times__doc__[] =
3321"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3322Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003323#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003325
Guido van Rossumb6775db1994-08-01 11:34:53 +00003326#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003327static char posix_setsid__doc__[] =
3328"setsid() -> None\n\
3329Call the system call setsid().";
3330
Barry Warsaw53699e91996-12-10 23:23:01 +00003331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003332posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003333{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003334 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003335 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003336 if (setsid() < 0)
3337 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003338 Py_INCREF(Py_None);
3339 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003340}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003341#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003342
Guido van Rossumb6775db1994-08-01 11:34:53 +00003343#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003344static char posix_setpgid__doc__[] =
3345"setpgid(pid, pgrp) -> None\n\
3346Call the system call setpgid().";
3347
Barry Warsaw53699e91996-12-10 23:23:01 +00003348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003349posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003350{
3351 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003352 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003353 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003354 if (setpgid(pid, pgrp) < 0)
3355 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003356 Py_INCREF(Py_None);
3357 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003358}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003359#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003360
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003361
Guido van Rossumb6775db1994-08-01 11:34:53 +00003362#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003363static char posix_tcgetpgrp__doc__[] =
3364"tcgetpgrp(fd) -> pgid\n\
3365Return the process group associated with the terminal given by a fd.";
3366
Barry Warsaw53699e91996-12-10 23:23:01 +00003367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003368posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003369{
3370 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003371 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003372 return NULL;
3373 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003374 if (pgid < 0)
3375 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003376 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003377}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003378#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003380
Guido van Rossumb6775db1994-08-01 11:34:53 +00003381#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003382static char posix_tcsetpgrp__doc__[] =
3383"tcsetpgrp(fd, pgid) -> None\n\
3384Set the process group associated with the terminal given by a fd.";
3385
Barry Warsaw53699e91996-12-10 23:23:01 +00003386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003387posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003388{
3389 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003390 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003391 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003392 if (tcsetpgrp(fd, pgid) < 0)
3393 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003394 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003395 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003396}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003397#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003398
Guido van Rossum687dd131993-05-17 08:34:16 +00003399/* Functions acting on file descriptors */
3400
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003401static char posix_open__doc__[] =
3402"open(filename, flag [, mode=0777]) -> fd\n\
3403Open a file (for low level IO).";
3404
Barry Warsaw53699e91996-12-10 23:23:01 +00003405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003406posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003407{
Mark Hammondef8b6542001-05-13 08:04:26 +00003408 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003409 int flag;
3410 int mode = 0777;
3411 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003412 if (!PyArg_ParseTuple(args, "eti|i",
3413 Py_FileSystemDefaultEncoding, &file,
3414 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003415 return NULL;
3416
Barry Warsaw53699e91996-12-10 23:23:01 +00003417 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003418 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003419 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003420 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003421 return posix_error_with_allocated_filename(file);
3422 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003423 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003424}
3425
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003426
3427static char posix_close__doc__[] =
3428"close(fd) -> None\n\
3429Close a file descriptor (for low level IO).";
3430
Barry Warsaw53699e91996-12-10 23:23:01 +00003431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003432posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003433{
3434 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003435 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003436 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003437 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003438 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003439 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003440 if (res < 0)
3441 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003442 Py_INCREF(Py_None);
3443 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003444}
3445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003446
3447static char posix_dup__doc__[] =
3448"dup(fd) -> fd2\n\
3449Return a duplicate of a file descriptor.";
3450
Barry Warsaw53699e91996-12-10 23:23:01 +00003451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003452posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003453{
3454 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003455 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003456 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003457 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003458 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003459 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003460 if (fd < 0)
3461 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003462 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003463}
3464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003465
3466static char posix_dup2__doc__[] =
3467"dup2(fd, fd2) -> None\n\
3468Duplicate file descriptor.";
3469
Barry Warsaw53699e91996-12-10 23:23:01 +00003470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003471posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003472{
3473 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003474 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003475 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003476 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003477 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003478 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003479 if (res < 0)
3480 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003481 Py_INCREF(Py_None);
3482 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003483}
3484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003485
3486static char posix_lseek__doc__[] =
3487"lseek(fd, pos, how) -> newpos\n\
3488Set the current position of a file descriptor.";
3489
Barry Warsaw53699e91996-12-10 23:23:01 +00003490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003491posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003492{
3493 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003494#ifdef MS_WIN64
3495 LONG_LONG pos, res;
3496#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003497 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003498#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003499 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003500 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003501 return NULL;
3502#ifdef SEEK_SET
3503 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3504 switch (how) {
3505 case 0: how = SEEK_SET; break;
3506 case 1: how = SEEK_CUR; break;
3507 case 2: how = SEEK_END; break;
3508 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003509#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003510
3511#if !defined(HAVE_LARGEFILE_SUPPORT)
3512 pos = PyInt_AsLong(posobj);
3513#else
3514 pos = PyLong_Check(posobj) ?
3515 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3516#endif
3517 if (PyErr_Occurred())
3518 return NULL;
3519
Barry Warsaw53699e91996-12-10 23:23:01 +00003520 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003521#ifdef MS_WIN64
3522 res = _lseeki64(fd, pos, how);
3523#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003524 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003525#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003526 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003527 if (res < 0)
3528 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003529
3530#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003531 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003532#else
3533 return PyLong_FromLongLong(res);
3534#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003535}
3536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003537
3538static char posix_read__doc__[] =
3539"read(fd, buffersize) -> string\n\
3540Read a file descriptor.";
3541
Barry Warsaw53699e91996-12-10 23:23:01 +00003542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003543posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003544{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003545 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003546 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003547 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003548 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003549 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003550 if (buffer == NULL)
3551 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003552 Py_BEGIN_ALLOW_THREADS
3553 n = read(fd, PyString_AsString(buffer), size);
3554 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003555 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003556 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003557 return posix_error();
3558 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003559 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003560 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003561 return buffer;
3562}
3563
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003564
3565static char posix_write__doc__[] =
3566"write(fd, string) -> byteswritten\n\
3567Write a string to a file descriptor.";
3568
Barry Warsaw53699e91996-12-10 23:23:01 +00003569static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003570posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003571{
3572 int fd, size;
3573 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003574 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003575 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003576 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003577 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003578 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003579 if (size < 0)
3580 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003581 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003582}
3583
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003584
3585static char posix_fstat__doc__[]=
3586"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3587Like stat(), but for an open file descriptor.";
3588
Barry Warsaw53699e91996-12-10 23:23:01 +00003589static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003590posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003591{
3592 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003593 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003594 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003595 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003596 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003597 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003598 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003599 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003600 if (res != 0)
3601 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003602
3603 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003604}
3605
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003606
3607static char posix_fdopen__doc__[] =
3608"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3609Return an open file object connected to a file descriptor.";
3610
Barry Warsaw53699e91996-12-10 23:23:01 +00003611static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003612posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003613{
Guido van Rossum687dd131993-05-17 08:34:16 +00003614 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003615 char *mode = "r";
3616 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003617 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003618 PyObject *f;
3619 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003620 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003621
Barry Warsaw53699e91996-12-10 23:23:01 +00003622 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003623 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003624 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003625 if (fp == NULL)
3626 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003627 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003628 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003629 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003630 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003631}
3632
Skip Montanaro1517d842000-07-19 14:34:14 +00003633static char posix_isatty__doc__[] =
3634"isatty(fd) -> Boolean\n\
3635Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003636connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003637
3638static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003639posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003640{
3641 int fd;
3642 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3643 return NULL;
3644 return Py_BuildValue("i", isatty(fd));
3645}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003646
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003647#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003648static char posix_pipe__doc__[] =
3649"pipe() -> (read_end, write_end)\n\
3650Create a pipe.";
3651
Barry Warsaw53699e91996-12-10 23:23:01 +00003652static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003653posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003654{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003655#if defined(PYOS_OS2)
3656 HFILE read, write;
3657 APIRET rc;
3658
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003659 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003660 return NULL;
3661
3662 Py_BEGIN_ALLOW_THREADS
3663 rc = DosCreatePipe( &read, &write, 4096);
3664 Py_END_ALLOW_THREADS
3665 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003666 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003667
3668 return Py_BuildValue("(ii)", read, write);
3669#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003670#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003671 int fds[2];
3672 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003673 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003674 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003675 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003676 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003677 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003678 if (res != 0)
3679 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003680 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003681#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003682 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003683 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003684 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003685 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003686 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003687 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003688 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003689 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003690 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003691 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003692 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3693 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003694 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003695#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003696#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003697}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003698#endif /* HAVE_PIPE */
3699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003700
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003701#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003702static char posix_mkfifo__doc__[] =
3703"mkfifo(file, [, mode=0666]) -> None\n\
3704Create a FIFO (a POSIX named pipe).";
3705
Barry Warsaw53699e91996-12-10 23:23:01 +00003706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003707posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003708{
3709 char *file;
3710 int mode = 0666;
3711 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003712 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003713 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003714 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003715 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003716 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003717 if (res < 0)
3718 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003719 Py_INCREF(Py_None);
3720 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003721}
3722#endif
3723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003724
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003725#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003726static char posix_ftruncate__doc__[] =
3727"ftruncate(fd, length) -> None\n\
3728Truncate a file to a specified length.";
3729
Barry Warsaw53699e91996-12-10 23:23:01 +00003730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003731posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003732{
3733 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003734 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003735 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003736 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003737
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003738 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003739 return NULL;
3740
3741#if !defined(HAVE_LARGEFILE_SUPPORT)
3742 length = PyInt_AsLong(lenobj);
3743#else
3744 length = PyLong_Check(lenobj) ?
3745 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3746#endif
3747 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003748 return NULL;
3749
Barry Warsaw53699e91996-12-10 23:23:01 +00003750 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003751 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003752 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003753 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003754 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003755 return NULL;
3756 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003757 Py_INCREF(Py_None);
3758 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003759}
3760#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003761
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003762#ifdef NeXT
3763#define HAVE_PUTENV
3764/* Steve Spicklemire got this putenv from NeXTAnswers */
3765static int
3766putenv(char *newval)
3767{
3768 extern char **environ;
3769
3770 static int firstTime = 1;
3771 char **ep;
3772 char *cp;
3773 int esiz;
3774 char *np;
3775
3776 if (!(np = strchr(newval, '=')))
3777 return 1;
3778 *np = '\0';
3779
3780 /* look it up */
3781 for (ep=environ ; *ep ; ep++)
3782 {
3783 /* this should always be true... */
3784 if (cp = strchr(*ep, '='))
3785 {
3786 *cp = '\0';
3787 if (!strcmp(*ep, newval))
3788 {
3789 /* got it! */
3790 *cp = '=';
3791 break;
3792 }
3793 *cp = '=';
3794 }
3795 else
3796 {
3797 *np = '=';
3798 return 1;
3799 }
3800 }
3801
3802 *np = '=';
3803 if (*ep)
3804 {
3805 /* the string was already there:
3806 just replace it with the new one */
3807 *ep = newval;
3808 return 0;
3809 }
3810
3811 /* expand environ by one */
3812 for (esiz=2, ep=environ ; *ep ; ep++)
3813 esiz++;
3814 if (firstTime)
3815 {
3816 char **epp;
3817 char **newenv;
3818 if (!(newenv = malloc(esiz * sizeof(char *))))
3819 return 1;
3820
3821 for (ep=environ, epp=newenv ; *ep ;)
3822 *epp++ = *ep++;
3823 *epp++ = newval;
3824 *epp = (char *) 0;
3825 environ = newenv;
3826 }
3827 else
3828 {
3829 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3830 return 1;
3831 environ[esiz - 2] = newval;
3832 environ[esiz - 1] = (char *) 0;
3833 firstTime = 0;
3834 }
3835
3836 return 0;
3837}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003838#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003839
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003840
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003841#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003842static char posix_putenv__doc__[] =
3843"putenv(key, value) -> None\n\
3844Change or add an environment variable.";
3845
Fred Drake762e2061999-08-26 17:23:54 +00003846/* Save putenv() parameters as values here, so we can collect them when they
3847 * get re-set with another call for the same key. */
3848static PyObject *posix_putenv_garbage;
3849
Barry Warsaw53699e91996-12-10 23:23:01 +00003850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003851posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003852{
3853 char *s1, *s2;
3854 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003855 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003856
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003857 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003858 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003859
3860#if defined(PYOS_OS2)
3861 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3862 APIRET rc;
3863
3864 if (strlen(s2) == 0) /* If New Value is an Empty String */
3865 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3866
3867 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3868 if (rc != NO_ERROR)
3869 return os2_error(rc);
3870
3871 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3872 APIRET rc;
3873
3874 if (strlen(s2) == 0) /* If New Value is an Empty String */
3875 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3876
3877 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3878 if (rc != NO_ERROR)
3879 return os2_error(rc);
3880 } else {
3881#endif
3882
Fred Drake762e2061999-08-26 17:23:54 +00003883 /* XXX This can leak memory -- not easy to fix :-( */
3884 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3885 if (newstr == NULL)
3886 return PyErr_NoMemory();
3887 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003888 (void) sprintf(new, "%s=%s", s1, s2);
3889 if (putenv(new)) {
3890 posix_error();
3891 return NULL;
3892 }
Fred Drake762e2061999-08-26 17:23:54 +00003893 /* Install the first arg and newstr in posix_putenv_garbage;
3894 * this will cause previous value to be collected. This has to
3895 * happen after the real putenv() call because the old value
3896 * was still accessible until then. */
3897 if (PyDict_SetItem(posix_putenv_garbage,
3898 PyTuple_GET_ITEM(args, 0), newstr)) {
3899 /* really not much we can do; just leak */
3900 PyErr_Clear();
3901 }
3902 else {
3903 Py_DECREF(newstr);
3904 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003905
3906#if defined(PYOS_OS2)
3907 }
3908#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003909 Py_INCREF(Py_None);
3910 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003911}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003912#endif /* putenv */
3913
3914#ifdef HAVE_STRERROR
3915static char posix_strerror__doc__[] =
3916"strerror(code) -> string\n\
3917Translate an error code to a message string.";
3918
Guido van Rossumf68d8e52001-04-14 17:55:09 +00003919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003920posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003921{
3922 int code;
3923 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003924 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003925 return NULL;
3926 message = strerror(code);
3927 if (message == NULL) {
3928 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003929 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003930 return NULL;
3931 }
3932 return PyString_FromString(message);
3933}
3934#endif /* strerror */
3935
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003936
Guido van Rossumc9641791998-08-04 15:26:23 +00003937#ifdef HAVE_SYS_WAIT_H
3938
3939#ifdef WIFSTOPPED
3940static char posix_WIFSTOPPED__doc__[] =
3941"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003942Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003943
3944static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003945posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003946{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003947#ifdef UNION_WAIT
3948 union wait status;
3949#define status_i (status.w_status)
3950#else
3951 int status;
3952#define status_i status
3953#endif
3954 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003955
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003956 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003957 {
3958 return NULL;
3959 }
3960
3961 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003962#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003963}
3964#endif /* WIFSTOPPED */
3965
3966#ifdef WIFSIGNALED
3967static char posix_WIFSIGNALED__doc__[] =
3968"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003969Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003970
3971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003972posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003973{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003974#ifdef UNION_WAIT
3975 union wait status;
3976#define status_i (status.w_status)
3977#else
3978 int status;
3979#define status_i status
3980#endif
3981 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003982
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003983 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003984 {
3985 return NULL;
3986 }
3987
3988 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003989#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003990}
3991#endif /* WIFSIGNALED */
3992
3993#ifdef WIFEXITED
3994static char posix_WIFEXITED__doc__[] =
3995"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003996Return true if the process returning 'status' exited using the exit()\n\
3997system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003998
3999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004000posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004001{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004002#ifdef UNION_WAIT
4003 union wait status;
4004#define status_i (status.w_status)
4005#else
4006 int status;
4007#define status_i status
4008#endif
4009 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004010
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004011 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004012 {
4013 return NULL;
4014 }
4015
4016 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004017#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004018}
4019#endif /* WIFEXITED */
4020
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004021#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004022static char posix_WEXITSTATUS__doc__[] =
4023"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004024Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004025
4026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004027posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004028{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004029#ifdef UNION_WAIT
4030 union wait status;
4031#define status_i (status.w_status)
4032#else
4033 int status;
4034#define status_i status
4035#endif
4036 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004037
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004038 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004039 {
4040 return NULL;
4041 }
4042
4043 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004044#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004045}
4046#endif /* WEXITSTATUS */
4047
4048#ifdef WTERMSIG
4049static char posix_WTERMSIG__doc__[] =
4050"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004051Return the signal that terminated the process that provided the 'status'\n\
4052value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004053
4054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004055posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004056{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004057#ifdef UNION_WAIT
4058 union wait status;
4059#define status_i (status.w_status)
4060#else
4061 int status;
4062#define status_i status
4063#endif
4064 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004065
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004066 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004067 {
4068 return NULL;
4069 }
4070
4071 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004072#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004073}
4074#endif /* WTERMSIG */
4075
4076#ifdef WSTOPSIG
4077static char posix_WSTOPSIG__doc__[] =
4078"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004079Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004080
4081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004082posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004083{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004084#ifdef UNION_WAIT
4085 union wait status;
4086#define status_i (status.w_status)
4087#else
4088 int status;
4089#define status_i status
4090#endif
4091 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004092
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004093 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004094 {
4095 return NULL;
4096 }
4097
4098 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004099#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004100}
4101#endif /* WSTOPSIG */
4102
4103#endif /* HAVE_SYS_WAIT_H */
4104
4105
Guido van Rossum94f6f721999-01-06 18:42:14 +00004106#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004107#ifdef _SCO_DS
4108/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4109 needed definitions in sys/statvfs.h */
4110#define _SVID3
4111#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004112#include <sys/statvfs.h>
4113
4114static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004115"fstatvfs(fd) -> \n\
4116 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004117Perform an fstatvfs system call on the given fd.";
4118
4119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004120posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004121{
4122 int fd, res;
4123 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004124 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004125 return NULL;
4126 Py_BEGIN_ALLOW_THREADS
4127 res = fstatvfs(fd, &st);
4128 Py_END_ALLOW_THREADS
4129 if (res != 0)
4130 return posix_error();
4131#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004132 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004133 (long) st.f_bsize,
4134 (long) st.f_frsize,
4135 (long) st.f_blocks,
4136 (long) st.f_bfree,
4137 (long) st.f_bavail,
4138 (long) st.f_files,
4139 (long) st.f_ffree,
4140 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004141 (long) st.f_flag,
4142 (long) st.f_namemax);
4143#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004144 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004145 (long) st.f_bsize,
4146 (long) st.f_frsize,
4147 (LONG_LONG) st.f_blocks,
4148 (LONG_LONG) st.f_bfree,
4149 (LONG_LONG) st.f_bavail,
4150 (LONG_LONG) st.f_files,
4151 (LONG_LONG) st.f_ffree,
4152 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004153 (long) st.f_flag,
4154 (long) st.f_namemax);
4155#endif
4156}
4157#endif /* HAVE_FSTATVFS */
4158
4159
4160#if defined(HAVE_STATVFS)
4161#include <sys/statvfs.h>
4162
4163static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004164"statvfs(path) -> \n\
4165 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004166Perform a statvfs system call on the given path.";
4167
4168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004169posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004170{
4171 char *path;
4172 int res;
4173 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004174 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004175 return NULL;
4176 Py_BEGIN_ALLOW_THREADS
4177 res = statvfs(path, &st);
4178 Py_END_ALLOW_THREADS
4179 if (res != 0)
4180 return posix_error_with_filename(path);
4181#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004182 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004183 (long) st.f_bsize,
4184 (long) st.f_frsize,
4185 (long) st.f_blocks,
4186 (long) st.f_bfree,
4187 (long) st.f_bavail,
4188 (long) st.f_files,
4189 (long) st.f_ffree,
4190 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004191 (long) st.f_flag,
4192 (long) st.f_namemax);
4193#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004194 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004195 (long) st.f_bsize,
4196 (long) st.f_frsize,
4197 (LONG_LONG) st.f_blocks,
4198 (LONG_LONG) st.f_bfree,
4199 (LONG_LONG) st.f_bavail,
4200 (LONG_LONG) st.f_files,
4201 (LONG_LONG) st.f_ffree,
4202 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004203 (long) st.f_flag,
4204 (long) st.f_namemax);
4205#endif
4206}
4207#endif /* HAVE_STATVFS */
4208
4209
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004210#ifdef HAVE_TEMPNAM
4211static char posix_tempnam__doc__[] = "\
4212tempnam([dir[, prefix]]) -> string\n\
4213Return a unique name for a temporary file.\n\
4214The directory and a short may be specified as strings; they may be omitted\n\
4215or None if not needed.";
4216
4217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004218posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004219{
4220 PyObject *result = NULL;
4221 char *dir = NULL;
4222 char *pfx = NULL;
4223 char *name;
4224
4225 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4226 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004227
4228 if (PyErr_Warn(PyExc_RuntimeWarning,
4229 "tempnam is a potential security risk to your program") < 0)
4230 return NULL;
4231
Fred Drake78b71c22001-07-17 20:37:36 +00004232#ifdef MS_WIN32
4233 name = _tempnam(dir, pfx);
4234#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004235 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004236#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004237 if (name == NULL)
4238 return PyErr_NoMemory();
4239 result = PyString_FromString(name);
4240 free(name);
4241 return result;
4242}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004243#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004244
4245
4246#ifdef HAVE_TMPFILE
4247static char posix_tmpfile__doc__[] = "\
4248tmpfile() -> file object\n\
4249Create a temporary file with no directory entries.";
4250
4251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004252posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004253{
4254 FILE *fp;
4255
4256 if (!PyArg_ParseTuple(args, ":tmpfile"))
4257 return NULL;
4258 fp = tmpfile();
4259 if (fp == NULL)
4260 return posix_error();
4261 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4262}
4263#endif
4264
4265
4266#ifdef HAVE_TMPNAM
4267static char posix_tmpnam__doc__[] = "\
4268tmpnam() -> string\n\
4269Return a unique name for a temporary file.";
4270
4271static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004272posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004273{
4274 char buffer[L_tmpnam];
4275 char *name;
4276
4277 if (!PyArg_ParseTuple(args, ":tmpnam"))
4278 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004279
4280 if (PyErr_Warn(PyExc_RuntimeWarning,
4281 "tmpnam is a potential security risk to your program") < 0)
4282 return NULL;
4283
Greg Wardb48bc172000-03-01 21:51:56 +00004284#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004285 name = tmpnam_r(buffer);
4286#else
4287 name = tmpnam(buffer);
4288#endif
4289 if (name == NULL) {
4290 PyErr_SetObject(PyExc_OSError,
4291 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004292#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004293 "unexpected NULL from tmpnam_r"
4294#else
4295 "unexpected NULL from tmpnam"
4296#endif
4297 ));
4298 return NULL;
4299 }
4300 return PyString_FromString(buffer);
4301}
4302#endif
4303
4304
Fred Drakec9680921999-12-13 16:37:25 +00004305/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4306 * It maps strings representing configuration variable names to
4307 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004308 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004309 * rarely-used constants. There are three separate tables that use
4310 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004311 *
4312 * This code is always included, even if none of the interfaces that
4313 * need it are included. The #if hackery needed to avoid it would be
4314 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004315 */
4316struct constdef {
4317 char *name;
4318 long value;
4319};
4320
Fred Drake12c6e2d1999-12-14 21:25:03 +00004321static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004322conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4323 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004324{
4325 if (PyInt_Check(arg)) {
4326 *valuep = PyInt_AS_LONG(arg);
4327 return 1;
4328 }
4329 if (PyString_Check(arg)) {
4330 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004331 size_t lo = 0;
4332 size_t mid;
4333 size_t hi = tablesize;
4334 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004335 char *confname = PyString_AS_STRING(arg);
4336 while (lo < hi) {
4337 mid = (lo + hi) / 2;
4338 cmp = strcmp(confname, table[mid].name);
4339 if (cmp < 0)
4340 hi = mid;
4341 else if (cmp > 0)
4342 lo = mid + 1;
4343 else {
4344 *valuep = table[mid].value;
4345 return 1;
4346 }
4347 }
4348 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4349 }
4350 else
4351 PyErr_SetString(PyExc_TypeError,
4352 "configuration names must be strings or integers");
4353 return 0;
4354}
4355
4356
4357#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4358static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004359#ifdef _PC_ABI_AIO_XFER_MAX
4360 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4361#endif
4362#ifdef _PC_ABI_ASYNC_IO
4363 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4364#endif
Fred Drakec9680921999-12-13 16:37:25 +00004365#ifdef _PC_ASYNC_IO
4366 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4367#endif
4368#ifdef _PC_CHOWN_RESTRICTED
4369 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4370#endif
4371#ifdef _PC_FILESIZEBITS
4372 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4373#endif
4374#ifdef _PC_LAST
4375 {"PC_LAST", _PC_LAST},
4376#endif
4377#ifdef _PC_LINK_MAX
4378 {"PC_LINK_MAX", _PC_LINK_MAX},
4379#endif
4380#ifdef _PC_MAX_CANON
4381 {"PC_MAX_CANON", _PC_MAX_CANON},
4382#endif
4383#ifdef _PC_MAX_INPUT
4384 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4385#endif
4386#ifdef _PC_NAME_MAX
4387 {"PC_NAME_MAX", _PC_NAME_MAX},
4388#endif
4389#ifdef _PC_NO_TRUNC
4390 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4391#endif
4392#ifdef _PC_PATH_MAX
4393 {"PC_PATH_MAX", _PC_PATH_MAX},
4394#endif
4395#ifdef _PC_PIPE_BUF
4396 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4397#endif
4398#ifdef _PC_PRIO_IO
4399 {"PC_PRIO_IO", _PC_PRIO_IO},
4400#endif
4401#ifdef _PC_SOCK_MAXBUF
4402 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4403#endif
4404#ifdef _PC_SYNC_IO
4405 {"PC_SYNC_IO", _PC_SYNC_IO},
4406#endif
4407#ifdef _PC_VDISABLE
4408 {"PC_VDISABLE", _PC_VDISABLE},
4409#endif
4410};
4411
Fred Drakec9680921999-12-13 16:37:25 +00004412static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004413conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004414{
4415 return conv_confname(arg, valuep, posix_constants_pathconf,
4416 sizeof(posix_constants_pathconf)
4417 / sizeof(struct constdef));
4418}
4419#endif
4420
4421#ifdef HAVE_FPATHCONF
4422static char posix_fpathconf__doc__[] = "\
4423fpathconf(fd, name) -> integer\n\
4424Return the configuration limit name for the file descriptor fd.\n\
4425If there is no limit, return -1.";
4426
4427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004428posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004429{
4430 PyObject *result = NULL;
4431 int name, fd;
4432
Fred Drake12c6e2d1999-12-14 21:25:03 +00004433 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4434 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004435 long limit;
4436
4437 errno = 0;
4438 limit = fpathconf(fd, name);
4439 if (limit == -1 && errno != 0)
4440 posix_error();
4441 else
4442 result = PyInt_FromLong(limit);
4443 }
4444 return result;
4445}
4446#endif
4447
4448
4449#ifdef HAVE_PATHCONF
4450static char posix_pathconf__doc__[] = "\
4451pathconf(path, name) -> integer\n\
4452Return the configuration limit name for the file or directory path.\n\
4453If there is no limit, return -1.";
4454
4455static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004456posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004457{
4458 PyObject *result = NULL;
4459 int name;
4460 char *path;
4461
4462 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4463 conv_path_confname, &name)) {
4464 long limit;
4465
4466 errno = 0;
4467 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004468 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004469 if (errno == EINVAL)
4470 /* could be a path or name problem */
4471 posix_error();
4472 else
4473 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004474 }
Fred Drakec9680921999-12-13 16:37:25 +00004475 else
4476 result = PyInt_FromLong(limit);
4477 }
4478 return result;
4479}
4480#endif
4481
4482#ifdef HAVE_CONFSTR
4483static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004484#ifdef _CS_ARCHITECTURE
4485 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4486#endif
4487#ifdef _CS_HOSTNAME
4488 {"CS_HOSTNAME", _CS_HOSTNAME},
4489#endif
4490#ifdef _CS_HW_PROVIDER
4491 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4492#endif
4493#ifdef _CS_HW_SERIAL
4494 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4495#endif
4496#ifdef _CS_INITTAB_NAME
4497 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4498#endif
Fred Drakec9680921999-12-13 16:37:25 +00004499#ifdef _CS_LFS64_CFLAGS
4500 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4501#endif
4502#ifdef _CS_LFS64_LDFLAGS
4503 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4504#endif
4505#ifdef _CS_LFS64_LIBS
4506 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4507#endif
4508#ifdef _CS_LFS64_LINTFLAGS
4509 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4510#endif
4511#ifdef _CS_LFS_CFLAGS
4512 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4513#endif
4514#ifdef _CS_LFS_LDFLAGS
4515 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4516#endif
4517#ifdef _CS_LFS_LIBS
4518 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4519#endif
4520#ifdef _CS_LFS_LINTFLAGS
4521 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4522#endif
Fred Draked86ed291999-12-15 15:34:33 +00004523#ifdef _CS_MACHINE
4524 {"CS_MACHINE", _CS_MACHINE},
4525#endif
Fred Drakec9680921999-12-13 16:37:25 +00004526#ifdef _CS_PATH
4527 {"CS_PATH", _CS_PATH},
4528#endif
Fred Draked86ed291999-12-15 15:34:33 +00004529#ifdef _CS_RELEASE
4530 {"CS_RELEASE", _CS_RELEASE},
4531#endif
4532#ifdef _CS_SRPC_DOMAIN
4533 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4534#endif
4535#ifdef _CS_SYSNAME
4536 {"CS_SYSNAME", _CS_SYSNAME},
4537#endif
4538#ifdef _CS_VERSION
4539 {"CS_VERSION", _CS_VERSION},
4540#endif
Fred Drakec9680921999-12-13 16:37:25 +00004541#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4542 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4543#endif
4544#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4545 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4546#endif
4547#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4548 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4549#endif
4550#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4551 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4552#endif
4553#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4554 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4555#endif
4556#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4557 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4558#endif
4559#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4560 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4561#endif
4562#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4563 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4564#endif
4565#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4566 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4567#endif
4568#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4569 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4570#endif
4571#ifdef _CS_XBS5_LP64_OFF64_LIBS
4572 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4573#endif
4574#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4575 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4576#endif
4577#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4578 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4579#endif
4580#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4581 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4582#endif
4583#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4584 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4585#endif
4586#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4587 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4588#endif
Fred Draked86ed291999-12-15 15:34:33 +00004589#ifdef _MIPS_CS_AVAIL_PROCESSORS
4590 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4591#endif
4592#ifdef _MIPS_CS_BASE
4593 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4594#endif
4595#ifdef _MIPS_CS_HOSTID
4596 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4597#endif
4598#ifdef _MIPS_CS_HW_NAME
4599 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4600#endif
4601#ifdef _MIPS_CS_NUM_PROCESSORS
4602 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4603#endif
4604#ifdef _MIPS_CS_OSREL_MAJ
4605 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4606#endif
4607#ifdef _MIPS_CS_OSREL_MIN
4608 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4609#endif
4610#ifdef _MIPS_CS_OSREL_PATCH
4611 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4612#endif
4613#ifdef _MIPS_CS_OS_NAME
4614 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4615#endif
4616#ifdef _MIPS_CS_OS_PROVIDER
4617 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4618#endif
4619#ifdef _MIPS_CS_PROCESSORS
4620 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4621#endif
4622#ifdef _MIPS_CS_SERIAL
4623 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4624#endif
4625#ifdef _MIPS_CS_VENDOR
4626 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4627#endif
Fred Drakec9680921999-12-13 16:37:25 +00004628};
4629
4630static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004631conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004632{
4633 return conv_confname(arg, valuep, posix_constants_confstr,
4634 sizeof(posix_constants_confstr)
4635 / sizeof(struct constdef));
4636}
4637
4638static char posix_confstr__doc__[] = "\
4639confstr(name) -> string\n\
4640Return a string-valued system configuration variable.";
4641
4642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004643posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004644{
4645 PyObject *result = NULL;
4646 int name;
4647 char buffer[64];
4648
4649 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4650 int len = confstr(name, buffer, sizeof(buffer));
4651
Fred Drakec9680921999-12-13 16:37:25 +00004652 errno = 0;
4653 if (len == 0) {
4654 if (errno != 0)
4655 posix_error();
4656 else
4657 result = PyString_FromString("");
4658 }
4659 else {
4660 if (len >= sizeof(buffer)) {
4661 result = PyString_FromStringAndSize(NULL, len);
4662 if (result != NULL)
4663 confstr(name, PyString_AS_STRING(result), len+1);
4664 }
4665 else
4666 result = PyString_FromString(buffer);
4667 }
4668 }
4669 return result;
4670}
4671#endif
4672
4673
4674#ifdef HAVE_SYSCONF
4675static struct constdef posix_constants_sysconf[] = {
4676#ifdef _SC_2_CHAR_TERM
4677 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4678#endif
4679#ifdef _SC_2_C_BIND
4680 {"SC_2_C_BIND", _SC_2_C_BIND},
4681#endif
4682#ifdef _SC_2_C_DEV
4683 {"SC_2_C_DEV", _SC_2_C_DEV},
4684#endif
4685#ifdef _SC_2_C_VERSION
4686 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4687#endif
4688#ifdef _SC_2_FORT_DEV
4689 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4690#endif
4691#ifdef _SC_2_FORT_RUN
4692 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4693#endif
4694#ifdef _SC_2_LOCALEDEF
4695 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4696#endif
4697#ifdef _SC_2_SW_DEV
4698 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4699#endif
4700#ifdef _SC_2_UPE
4701 {"SC_2_UPE", _SC_2_UPE},
4702#endif
4703#ifdef _SC_2_VERSION
4704 {"SC_2_VERSION", _SC_2_VERSION},
4705#endif
Fred Draked86ed291999-12-15 15:34:33 +00004706#ifdef _SC_ABI_ASYNCHRONOUS_IO
4707 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4708#endif
4709#ifdef _SC_ACL
4710 {"SC_ACL", _SC_ACL},
4711#endif
Fred Drakec9680921999-12-13 16:37:25 +00004712#ifdef _SC_AIO_LISTIO_MAX
4713 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4714#endif
Fred Drakec9680921999-12-13 16:37:25 +00004715#ifdef _SC_AIO_MAX
4716 {"SC_AIO_MAX", _SC_AIO_MAX},
4717#endif
4718#ifdef _SC_AIO_PRIO_DELTA_MAX
4719 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4720#endif
4721#ifdef _SC_ARG_MAX
4722 {"SC_ARG_MAX", _SC_ARG_MAX},
4723#endif
4724#ifdef _SC_ASYNCHRONOUS_IO
4725 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4726#endif
4727#ifdef _SC_ATEXIT_MAX
4728 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4729#endif
Fred Draked86ed291999-12-15 15:34:33 +00004730#ifdef _SC_AUDIT
4731 {"SC_AUDIT", _SC_AUDIT},
4732#endif
Fred Drakec9680921999-12-13 16:37:25 +00004733#ifdef _SC_AVPHYS_PAGES
4734 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4735#endif
4736#ifdef _SC_BC_BASE_MAX
4737 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4738#endif
4739#ifdef _SC_BC_DIM_MAX
4740 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4741#endif
4742#ifdef _SC_BC_SCALE_MAX
4743 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4744#endif
4745#ifdef _SC_BC_STRING_MAX
4746 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4747#endif
Fred Draked86ed291999-12-15 15:34:33 +00004748#ifdef _SC_CAP
4749 {"SC_CAP", _SC_CAP},
4750#endif
Fred Drakec9680921999-12-13 16:37:25 +00004751#ifdef _SC_CHARCLASS_NAME_MAX
4752 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4753#endif
4754#ifdef _SC_CHAR_BIT
4755 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4756#endif
4757#ifdef _SC_CHAR_MAX
4758 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4759#endif
4760#ifdef _SC_CHAR_MIN
4761 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4762#endif
4763#ifdef _SC_CHILD_MAX
4764 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4765#endif
4766#ifdef _SC_CLK_TCK
4767 {"SC_CLK_TCK", _SC_CLK_TCK},
4768#endif
4769#ifdef _SC_COHER_BLKSZ
4770 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4771#endif
4772#ifdef _SC_COLL_WEIGHTS_MAX
4773 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4774#endif
4775#ifdef _SC_DCACHE_ASSOC
4776 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4777#endif
4778#ifdef _SC_DCACHE_BLKSZ
4779 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4780#endif
4781#ifdef _SC_DCACHE_LINESZ
4782 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4783#endif
4784#ifdef _SC_DCACHE_SZ
4785 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4786#endif
4787#ifdef _SC_DCACHE_TBLKSZ
4788 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4789#endif
4790#ifdef _SC_DELAYTIMER_MAX
4791 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4792#endif
4793#ifdef _SC_EQUIV_CLASS_MAX
4794 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4795#endif
4796#ifdef _SC_EXPR_NEST_MAX
4797 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4798#endif
4799#ifdef _SC_FSYNC
4800 {"SC_FSYNC", _SC_FSYNC},
4801#endif
4802#ifdef _SC_GETGR_R_SIZE_MAX
4803 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4804#endif
4805#ifdef _SC_GETPW_R_SIZE_MAX
4806 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4807#endif
4808#ifdef _SC_ICACHE_ASSOC
4809 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4810#endif
4811#ifdef _SC_ICACHE_BLKSZ
4812 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4813#endif
4814#ifdef _SC_ICACHE_LINESZ
4815 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4816#endif
4817#ifdef _SC_ICACHE_SZ
4818 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4819#endif
Fred Draked86ed291999-12-15 15:34:33 +00004820#ifdef _SC_INF
4821 {"SC_INF", _SC_INF},
4822#endif
Fred Drakec9680921999-12-13 16:37:25 +00004823#ifdef _SC_INT_MAX
4824 {"SC_INT_MAX", _SC_INT_MAX},
4825#endif
4826#ifdef _SC_INT_MIN
4827 {"SC_INT_MIN", _SC_INT_MIN},
4828#endif
4829#ifdef _SC_IOV_MAX
4830 {"SC_IOV_MAX", _SC_IOV_MAX},
4831#endif
Fred Draked86ed291999-12-15 15:34:33 +00004832#ifdef _SC_IP_SECOPTS
4833 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4834#endif
Fred Drakec9680921999-12-13 16:37:25 +00004835#ifdef _SC_JOB_CONTROL
4836 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4837#endif
Fred Draked86ed291999-12-15 15:34:33 +00004838#ifdef _SC_KERN_POINTERS
4839 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4840#endif
4841#ifdef _SC_KERN_SIM
4842 {"SC_KERN_SIM", _SC_KERN_SIM},
4843#endif
Fred Drakec9680921999-12-13 16:37:25 +00004844#ifdef _SC_LINE_MAX
4845 {"SC_LINE_MAX", _SC_LINE_MAX},
4846#endif
4847#ifdef _SC_LOGIN_NAME_MAX
4848 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4849#endif
4850#ifdef _SC_LOGNAME_MAX
4851 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4852#endif
4853#ifdef _SC_LONG_BIT
4854 {"SC_LONG_BIT", _SC_LONG_BIT},
4855#endif
Fred Draked86ed291999-12-15 15:34:33 +00004856#ifdef _SC_MAC
4857 {"SC_MAC", _SC_MAC},
4858#endif
Fred Drakec9680921999-12-13 16:37:25 +00004859#ifdef _SC_MAPPED_FILES
4860 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4861#endif
4862#ifdef _SC_MAXPID
4863 {"SC_MAXPID", _SC_MAXPID},
4864#endif
4865#ifdef _SC_MB_LEN_MAX
4866 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4867#endif
4868#ifdef _SC_MEMLOCK
4869 {"SC_MEMLOCK", _SC_MEMLOCK},
4870#endif
4871#ifdef _SC_MEMLOCK_RANGE
4872 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4873#endif
4874#ifdef _SC_MEMORY_PROTECTION
4875 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4876#endif
4877#ifdef _SC_MESSAGE_PASSING
4878 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4879#endif
Fred Draked86ed291999-12-15 15:34:33 +00004880#ifdef _SC_MMAP_FIXED_ALIGNMENT
4881 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4882#endif
Fred Drakec9680921999-12-13 16:37:25 +00004883#ifdef _SC_MQ_OPEN_MAX
4884 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4885#endif
4886#ifdef _SC_MQ_PRIO_MAX
4887 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4888#endif
Fred Draked86ed291999-12-15 15:34:33 +00004889#ifdef _SC_NACLS_MAX
4890 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4891#endif
Fred Drakec9680921999-12-13 16:37:25 +00004892#ifdef _SC_NGROUPS_MAX
4893 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4894#endif
4895#ifdef _SC_NL_ARGMAX
4896 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4897#endif
4898#ifdef _SC_NL_LANGMAX
4899 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4900#endif
4901#ifdef _SC_NL_MSGMAX
4902 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4903#endif
4904#ifdef _SC_NL_NMAX
4905 {"SC_NL_NMAX", _SC_NL_NMAX},
4906#endif
4907#ifdef _SC_NL_SETMAX
4908 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4909#endif
4910#ifdef _SC_NL_TEXTMAX
4911 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4912#endif
4913#ifdef _SC_NPROCESSORS_CONF
4914 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4915#endif
4916#ifdef _SC_NPROCESSORS_ONLN
4917 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4918#endif
Fred Draked86ed291999-12-15 15:34:33 +00004919#ifdef _SC_NPROC_CONF
4920 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4921#endif
4922#ifdef _SC_NPROC_ONLN
4923 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4924#endif
Fred Drakec9680921999-12-13 16:37:25 +00004925#ifdef _SC_NZERO
4926 {"SC_NZERO", _SC_NZERO},
4927#endif
4928#ifdef _SC_OPEN_MAX
4929 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4930#endif
4931#ifdef _SC_PAGESIZE
4932 {"SC_PAGESIZE", _SC_PAGESIZE},
4933#endif
4934#ifdef _SC_PAGE_SIZE
4935 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4936#endif
4937#ifdef _SC_PASS_MAX
4938 {"SC_PASS_MAX", _SC_PASS_MAX},
4939#endif
4940#ifdef _SC_PHYS_PAGES
4941 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4942#endif
4943#ifdef _SC_PII
4944 {"SC_PII", _SC_PII},
4945#endif
4946#ifdef _SC_PII_INTERNET
4947 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4948#endif
4949#ifdef _SC_PII_INTERNET_DGRAM
4950 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4951#endif
4952#ifdef _SC_PII_INTERNET_STREAM
4953 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4954#endif
4955#ifdef _SC_PII_OSI
4956 {"SC_PII_OSI", _SC_PII_OSI},
4957#endif
4958#ifdef _SC_PII_OSI_CLTS
4959 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4960#endif
4961#ifdef _SC_PII_OSI_COTS
4962 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4963#endif
4964#ifdef _SC_PII_OSI_M
4965 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4966#endif
4967#ifdef _SC_PII_SOCKET
4968 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4969#endif
4970#ifdef _SC_PII_XTI
4971 {"SC_PII_XTI", _SC_PII_XTI},
4972#endif
4973#ifdef _SC_POLL
4974 {"SC_POLL", _SC_POLL},
4975#endif
4976#ifdef _SC_PRIORITIZED_IO
4977 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4978#endif
4979#ifdef _SC_PRIORITY_SCHEDULING
4980 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4981#endif
4982#ifdef _SC_REALTIME_SIGNALS
4983 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4984#endif
4985#ifdef _SC_RE_DUP_MAX
4986 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4987#endif
4988#ifdef _SC_RTSIG_MAX
4989 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4990#endif
4991#ifdef _SC_SAVED_IDS
4992 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4993#endif
4994#ifdef _SC_SCHAR_MAX
4995 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4996#endif
4997#ifdef _SC_SCHAR_MIN
4998 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4999#endif
5000#ifdef _SC_SELECT
5001 {"SC_SELECT", _SC_SELECT},
5002#endif
5003#ifdef _SC_SEMAPHORES
5004 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5005#endif
5006#ifdef _SC_SEM_NSEMS_MAX
5007 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5008#endif
5009#ifdef _SC_SEM_VALUE_MAX
5010 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5011#endif
5012#ifdef _SC_SHARED_MEMORY_OBJECTS
5013 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5014#endif
5015#ifdef _SC_SHRT_MAX
5016 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5017#endif
5018#ifdef _SC_SHRT_MIN
5019 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5020#endif
5021#ifdef _SC_SIGQUEUE_MAX
5022 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5023#endif
5024#ifdef _SC_SIGRT_MAX
5025 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5026#endif
5027#ifdef _SC_SIGRT_MIN
5028 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5029#endif
Fred Draked86ed291999-12-15 15:34:33 +00005030#ifdef _SC_SOFTPOWER
5031 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5032#endif
Fred Drakec9680921999-12-13 16:37:25 +00005033#ifdef _SC_SPLIT_CACHE
5034 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5035#endif
5036#ifdef _SC_SSIZE_MAX
5037 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5038#endif
5039#ifdef _SC_STACK_PROT
5040 {"SC_STACK_PROT", _SC_STACK_PROT},
5041#endif
5042#ifdef _SC_STREAM_MAX
5043 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5044#endif
5045#ifdef _SC_SYNCHRONIZED_IO
5046 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5047#endif
5048#ifdef _SC_THREADS
5049 {"SC_THREADS", _SC_THREADS},
5050#endif
5051#ifdef _SC_THREAD_ATTR_STACKADDR
5052 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5053#endif
5054#ifdef _SC_THREAD_ATTR_STACKSIZE
5055 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5056#endif
5057#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5058 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5059#endif
5060#ifdef _SC_THREAD_KEYS_MAX
5061 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5062#endif
5063#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5064 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5065#endif
5066#ifdef _SC_THREAD_PRIO_INHERIT
5067 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5068#endif
5069#ifdef _SC_THREAD_PRIO_PROTECT
5070 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5071#endif
5072#ifdef _SC_THREAD_PROCESS_SHARED
5073 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5074#endif
5075#ifdef _SC_THREAD_SAFE_FUNCTIONS
5076 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5077#endif
5078#ifdef _SC_THREAD_STACK_MIN
5079 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5080#endif
5081#ifdef _SC_THREAD_THREADS_MAX
5082 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5083#endif
5084#ifdef _SC_TIMERS
5085 {"SC_TIMERS", _SC_TIMERS},
5086#endif
5087#ifdef _SC_TIMER_MAX
5088 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5089#endif
5090#ifdef _SC_TTY_NAME_MAX
5091 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5092#endif
5093#ifdef _SC_TZNAME_MAX
5094 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5095#endif
5096#ifdef _SC_T_IOV_MAX
5097 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5098#endif
5099#ifdef _SC_UCHAR_MAX
5100 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5101#endif
5102#ifdef _SC_UINT_MAX
5103 {"SC_UINT_MAX", _SC_UINT_MAX},
5104#endif
5105#ifdef _SC_UIO_MAXIOV
5106 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5107#endif
5108#ifdef _SC_ULONG_MAX
5109 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5110#endif
5111#ifdef _SC_USHRT_MAX
5112 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5113#endif
5114#ifdef _SC_VERSION
5115 {"SC_VERSION", _SC_VERSION},
5116#endif
5117#ifdef _SC_WORD_BIT
5118 {"SC_WORD_BIT", _SC_WORD_BIT},
5119#endif
5120#ifdef _SC_XBS5_ILP32_OFF32
5121 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5122#endif
5123#ifdef _SC_XBS5_ILP32_OFFBIG
5124 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5125#endif
5126#ifdef _SC_XBS5_LP64_OFF64
5127 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5128#endif
5129#ifdef _SC_XBS5_LPBIG_OFFBIG
5130 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5131#endif
5132#ifdef _SC_XOPEN_CRYPT
5133 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5134#endif
5135#ifdef _SC_XOPEN_ENH_I18N
5136 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5137#endif
5138#ifdef _SC_XOPEN_LEGACY
5139 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5140#endif
5141#ifdef _SC_XOPEN_REALTIME
5142 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5143#endif
5144#ifdef _SC_XOPEN_REALTIME_THREADS
5145 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5146#endif
5147#ifdef _SC_XOPEN_SHM
5148 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5149#endif
5150#ifdef _SC_XOPEN_UNIX
5151 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5152#endif
5153#ifdef _SC_XOPEN_VERSION
5154 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5155#endif
5156#ifdef _SC_XOPEN_XCU_VERSION
5157 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5158#endif
5159#ifdef _SC_XOPEN_XPG2
5160 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5161#endif
5162#ifdef _SC_XOPEN_XPG3
5163 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5164#endif
5165#ifdef _SC_XOPEN_XPG4
5166 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5167#endif
5168};
5169
5170static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005171conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005172{
5173 return conv_confname(arg, valuep, posix_constants_sysconf,
5174 sizeof(posix_constants_sysconf)
5175 / sizeof(struct constdef));
5176}
5177
5178static char posix_sysconf__doc__[] = "\
5179sysconf(name) -> integer\n\
5180Return an integer-valued system configuration variable.";
5181
5182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005183posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005184{
5185 PyObject *result = NULL;
5186 int name;
5187
5188 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5189 int value;
5190
5191 errno = 0;
5192 value = sysconf(name);
5193 if (value == -1 && errno != 0)
5194 posix_error();
5195 else
5196 result = PyInt_FromLong(value);
5197 }
5198 return result;
5199}
5200#endif
5201
5202
Fred Drakebec628d1999-12-15 18:31:10 +00005203/* This code is used to ensure that the tables of configuration value names
5204 * are in sorted order as required by conv_confname(), and also to build the
5205 * the exported dictionaries that are used to publish information about the
5206 * names available on the host platform.
5207 *
5208 * Sorting the table at runtime ensures that the table is properly ordered
5209 * when used, even for platforms we're not able to test on. It also makes
5210 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005211 */
Fred Drakebec628d1999-12-15 18:31:10 +00005212
5213static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005214cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005215{
5216 const struct constdef *c1 =
5217 (const struct constdef *) v1;
5218 const struct constdef *c2 =
5219 (const struct constdef *) v2;
5220
5221 return strcmp(c1->name, c2->name);
5222}
5223
5224static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005225setup_confname_table(struct constdef *table, size_t tablesize,
5226 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005227{
Fred Drakebec628d1999-12-15 18:31:10 +00005228 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005229 size_t i;
5230 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005231
5232 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5233 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005234 if (d == NULL)
5235 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005236
Barry Warsaw3155db32000-04-13 15:20:40 +00005237 for (i=0; i < tablesize; ++i) {
5238 PyObject *o = PyInt_FromLong(table[i].value);
5239 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5240 Py_XDECREF(o);
5241 Py_DECREF(d);
5242 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005243 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005244 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005245 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005246 status = PyDict_SetItemString(moddict, tablename, d);
5247 Py_DECREF(d);
5248 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005249}
5250
Fred Drakebec628d1999-12-15 18:31:10 +00005251/* Return -1 on failure, 0 on success. */
5252static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005253setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005254{
5255#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005256 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005257 sizeof(posix_constants_pathconf)
5258 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005259 "pathconf_names", moddict))
5260 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005261#endif
5262#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005263 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005264 sizeof(posix_constants_confstr)
5265 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005266 "confstr_names", moddict))
5267 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005268#endif
5269#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005270 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005271 sizeof(posix_constants_sysconf)
5272 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005273 "sysconf_names", moddict))
5274 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005275#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005276 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005277}
Fred Draked86ed291999-12-15 15:34:33 +00005278
5279
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005280static char posix_abort__doc__[] = "\
5281abort() -> does not return!\n\
5282Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5283in the hardest way possible on the hosting operating system.";
5284
5285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005286posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005287{
5288 if (!PyArg_ParseTuple(args, ":abort"))
5289 return NULL;
5290 abort();
5291 /*NOTREACHED*/
5292 Py_FatalError("abort() called from Python code didn't abort!");
5293 return NULL;
5294}
Fred Drakebec628d1999-12-15 18:31:10 +00005295
Tim Petersf58a7aa2000-09-22 10:05:54 +00005296#ifdef MS_WIN32
5297static char win32_startfile__doc__[] = "\
5298startfile(filepath) - Start a file with its associated application.\n\
5299\n\
5300This acts like double-clicking the file in Explorer, or giving the file\n\
5301name as an argument to the DOS \"start\" command: the file is opened\n\
5302with whatever application (if any) its extension is associated.\n\
5303\n\
5304startfile returns as soon as the associated application is launched.\n\
5305There is no option to wait for the application to close, and no way\n\
5306to retrieve the application's exit status.\n\
5307\n\
5308The filepath is relative to the current directory. If you want to use\n\
5309an absolute path, make sure the first character is not a slash (\"/\");\n\
5310the underlying Win32 ShellExecute function doesn't work if it is.";
5311
5312static PyObject *
5313win32_startfile(PyObject *self, PyObject *args)
5314{
5315 char *filepath;
5316 HINSTANCE rc;
5317 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5318 return NULL;
5319 Py_BEGIN_ALLOW_THREADS
5320 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5321 Py_END_ALLOW_THREADS
5322 if (rc <= (HINSTANCE)32)
5323 return win32_error("startfile", filepath);
5324 Py_INCREF(Py_None);
5325 return Py_None;
5326}
5327#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005328
5329static PyMethodDef posix_methods[] = {
5330 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5331#ifdef HAVE_TTYNAME
5332 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5333#endif
5334 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5335 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005336#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005337 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005338#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005339#ifdef HAVE_CTERMID
5340 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5341#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005342#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005343 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005344#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005345#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005346 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005347#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005348 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5349 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5350 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005351#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005352 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005353#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005354#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005355 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005356#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005357 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5358 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5359 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005360#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005361 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005362#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005363#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005364 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005365#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005366 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005367#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005368 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005369#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005370 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5371 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5372 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005373#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005374 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005375#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005376 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005377#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005378 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5379 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005380#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005381#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005382 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5383 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005384#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005385#ifdef HAVE_FORK1
5386 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5387#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005388#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005389 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005390#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005391#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005392 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005393#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005394#ifdef HAVE_FORKPTY
5395 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5396#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005397#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005398 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005399#endif /* HAVE_GETEGID */
5400#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005401 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005402#endif /* HAVE_GETEUID */
5403#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005404 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005405#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005406#ifdef HAVE_GETGROUPS
5407 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5408#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005409 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005410#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005411 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005412#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005413#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005414 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005415#endif /* HAVE_GETPPID */
5416#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005417 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005418#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005419#ifdef HAVE_GETLOGIN
5420 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5421#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005422#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005423 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005424#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005425#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005426 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005427#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005428#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005429 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005430#ifdef MS_WIN32
5431 {"popen2", win32_popen2, METH_VARARGS},
5432 {"popen3", win32_popen3, METH_VARARGS},
5433 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005434 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005435#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005436#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005437#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005438 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005439#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005440#ifdef HAVE_SETEUID
5441 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5442#endif /* HAVE_SETEUID */
5443#ifdef HAVE_SETEGID
5444 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5445#endif /* HAVE_SETEGID */
5446#ifdef HAVE_SETREUID
5447 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5448#endif /* HAVE_SETREUID */
5449#ifdef HAVE_SETREGID
5450 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5451#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005452#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005453 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005454#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005455#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005456 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005457#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005458#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005459 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005460#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005461#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005462 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005463#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005464#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005465 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005466#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005467#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005468 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005469#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005470#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005471 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005472#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005473#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005474 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005475#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005476 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5477 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5478 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5479 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5480 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5481 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5482 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5483 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5484 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005485 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005486#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005487 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005488#endif
5489#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005490 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005491#endif
5492#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005493 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005494#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005495#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005496 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005497#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005498#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005499 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005500#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005501#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005502 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005503#endif
5504#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005505 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005506#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005507#ifdef HAVE_SYS_WAIT_H
5508#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005509 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005510#endif /* WIFSTOPPED */
5511#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005512 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005513#endif /* WIFSIGNALED */
5514#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005515 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005516#endif /* WIFEXITED */
5517#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005518 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005519#endif /* WEXITSTATUS */
5520#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005521 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005522#endif /* WTERMSIG */
5523#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005524 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005525#endif /* WSTOPSIG */
5526#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005527#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005528 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005529#endif
5530#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005531 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005532#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005533#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005534 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5535#endif
5536#ifdef HAVE_TEMPNAM
5537 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5538#endif
5539#ifdef HAVE_TMPNAM
5540 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5541#endif
Fred Drakec9680921999-12-13 16:37:25 +00005542#ifdef HAVE_CONFSTR
5543 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5544#endif
5545#ifdef HAVE_SYSCONF
5546 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5547#endif
5548#ifdef HAVE_FPATHCONF
5549 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5550#endif
5551#ifdef HAVE_PATHCONF
5552 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5553#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005554 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005555#ifdef MS_WIN32
5556 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5557#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005558 {NULL, NULL} /* Sentinel */
5559};
5560
5561
Barry Warsaw4a342091996-12-19 23:50:02 +00005562static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005563ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005564{
5565 PyObject* v = PyInt_FromLong(value);
5566 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5567 return -1; /* triggers fatal error */
5568
5569 Py_DECREF(v);
5570 return 0;
5571}
5572
Guido van Rossumd48f2521997-12-05 22:19:34 +00005573#if defined(PYOS_OS2)
5574/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5575static int insertvalues(PyObject *d)
5576{
5577 APIRET rc;
5578 ULONG values[QSV_MAX+1];
5579 PyObject *v;
5580 char *ver, tmp[10];
5581
5582 Py_BEGIN_ALLOW_THREADS
5583 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5584 Py_END_ALLOW_THREADS
5585
5586 if (rc != NO_ERROR) {
5587 os2_error(rc);
5588 return -1;
5589 }
5590
5591 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5592 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5593 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5594 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5595 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5596 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5597 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5598
5599 switch (values[QSV_VERSION_MINOR]) {
5600 case 0: ver = "2.00"; break;
5601 case 10: ver = "2.10"; break;
5602 case 11: ver = "2.11"; break;
5603 case 30: ver = "3.00"; break;
5604 case 40: ver = "4.00"; break;
5605 case 50: ver = "5.00"; break;
5606 default:
5607 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5608 values[QSV_VERSION_MINOR]);
5609 ver = &tmp[0];
5610 }
5611
5612 /* Add Indicator of the Version of the Operating System */
5613 v = PyString_FromString(ver);
5614 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5615 return -1;
5616 Py_DECREF(v);
5617
5618 /* Add Indicator of Which Drive was Used to Boot the System */
5619 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5620 tmp[1] = ':';
5621 tmp[2] = '\0';
5622
5623 v = PyString_FromString(tmp);
5624 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5625 return -1;
5626 Py_DECREF(v);
5627
5628 return 0;
5629}
5630#endif
5631
Barry Warsaw4a342091996-12-19 23:50:02 +00005632static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005633all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005634{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005635#ifdef F_OK
5636 if (ins(d, "F_OK", (long)F_OK)) return -1;
5637#endif
5638#ifdef R_OK
5639 if (ins(d, "R_OK", (long)R_OK)) return -1;
5640#endif
5641#ifdef W_OK
5642 if (ins(d, "W_OK", (long)W_OK)) return -1;
5643#endif
5644#ifdef X_OK
5645 if (ins(d, "X_OK", (long)X_OK)) return -1;
5646#endif
Fred Drakec9680921999-12-13 16:37:25 +00005647#ifdef NGROUPS_MAX
5648 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5649#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005650#ifdef TMP_MAX
5651 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5652#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005653#ifdef WNOHANG
5654 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5655#endif
5656#ifdef O_RDONLY
5657 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5658#endif
5659#ifdef O_WRONLY
5660 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5661#endif
5662#ifdef O_RDWR
5663 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5664#endif
5665#ifdef O_NDELAY
5666 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5667#endif
5668#ifdef O_NONBLOCK
5669 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5670#endif
5671#ifdef O_APPEND
5672 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5673#endif
5674#ifdef O_DSYNC
5675 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5676#endif
5677#ifdef O_RSYNC
5678 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5679#endif
5680#ifdef O_SYNC
5681 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5682#endif
5683#ifdef O_NOCTTY
5684 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5685#endif
5686#ifdef O_CREAT
5687 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5688#endif
5689#ifdef O_EXCL
5690 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5691#endif
5692#ifdef O_TRUNC
5693 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5694#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005695#ifdef O_BINARY
5696 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5697#endif
5698#ifdef O_TEXT
5699 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5700#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005701
Guido van Rossum246bc171999-02-01 23:54:31 +00005702#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005703 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5704 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5705 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5706 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5707 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005708#endif
5709
Guido van Rossumd48f2521997-12-05 22:19:34 +00005710#if defined(PYOS_OS2)
5711 if (insertvalues(d)) return -1;
5712#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005713 return 0;
5714}
5715
5716
Tim Peters58e0a8c2001-05-14 22:32:33 +00005717#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005718#define INITFUNC initnt
5719#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005720
5721#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005722#define INITFUNC initos2
5723#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005724
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005725#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005726#define INITFUNC initposix
5727#define MODNAME "posix"
5728#endif
5729
Guido van Rossum3886bb61998-12-04 18:50:17 +00005730DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005731INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005732{
Barry Warsaw53699e91996-12-10 23:23:01 +00005733 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005734
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005735 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005736 posix_methods,
5737 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005738 (PyObject *)NULL,
5739 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005740 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005741
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005742 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005743 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005744 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005745 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005746 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005747
Barry Warsaw4a342091996-12-19 23:50:02 +00005748 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005749 return;
5750
Fred Drakebec628d1999-12-15 18:31:10 +00005751 if (setup_confname_tables(d))
5752 return;
5753
Barry Warsawca74da41999-02-09 19:31:45 +00005754 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005755
Guido van Rossumb3d39562000-01-31 18:41:26 +00005756#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005757 if (posix_putenv_garbage == NULL)
5758 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005759#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005760}