blob: 430a44a85835a1a59ff5dab99adead8a02e6741c [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 */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000049/* XXX Gosh I wish these were all moved into config.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
66#define HAVE_GETEGID 1
67#define HAVE_GETEUID 1
68#define HAVE_GETGID 1
69#define HAVE_GETPPID 1
70#define HAVE_GETUID 1
71#define HAVE_KILL 1
72#define HAVE_OPENDIR 1
73#define HAVE_PIPE 1
74#define HAVE_POPEN 1
75#define HAVE_SYSTEM 1
76#define HAVE_WAIT 1
77#else
78#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000079#define HAVE_GETCWD 1
80#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000081#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#define HAVE_EXECV 1
83#define HAVE_PIPE 1
84#define HAVE_POPEN 1
85#define HAVE_SYSTEM 1
86#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000087#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#else /* all other compilers */
89/* Unix functions that the configure script doesn't check for */
90#define HAVE_EXECV 1
91#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000092#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
93#define HAVE_FORK1 1
94#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000095#define HAVE_GETCWD 1
96#define HAVE_GETEGID 1
97#define HAVE_GETEUID 1
98#define HAVE_GETGID 1
99#define HAVE_GETPPID 1
100#define HAVE_GETUID 1
101#define HAVE_KILL 1
102#define HAVE_OPENDIR 1
103#define HAVE_PIPE 1
104#define HAVE_POPEN 1
105#define HAVE_SYSTEM 1
106#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000107#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#endif /* _MSC_VER */
109#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000110#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000111#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000112
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000114
Guido van Rossumb6775db1994-08-01 11:34:53 +0000115#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000116#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000117#endif
118
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000119#if defined(sun) && !defined(__SVR4)
120/* SunOS 4.1.4 doesn't have prototypes for these: */
121extern int rename(const char *, const char *);
122extern int pclose(FILE *);
123extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000124extern int fsync(int);
125extern int lstat(const char *, struct stat *);
126extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000127#endif
128
Guido van Rossum36bc6801995-06-14 22:54:23 +0000129#ifdef NeXT
130/* NeXT's <unistd.h> and <utime.h> aren't worth much */
131#undef HAVE_UNISTD_H
132#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000133#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000134/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000135#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000136#endif
137
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000138#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int chmod(const char *, mode_t);
156extern int chown(const char *, uid_t, gid_t);
157extern char *getcwd(char *, int);
158extern char *strerror(int);
159extern int link(const char *, const char *);
160extern int rename(const char *, const char *);
161extern int stat(const char *, struct stat *);
162extern int unlink(const char *);
163extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000164#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000166#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000167#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000168extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000169#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000170#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000171
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#ifdef HAVE_UTIME_H
175#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000176#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000178#ifdef HAVE_SYS_UTIME_H
179#include <sys/utime.h>
180#define HAVE_UTIME_H /* pretend we do for the rest of this file */
181#endif /* HAVE_SYS_UTIME_H */
182
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#ifdef HAVE_SYS_TIMES_H
184#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000185#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186
187#ifdef HAVE_SYS_PARAM_H
188#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_UTSNAME_H
192#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifndef MAXPATHLEN
196#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#define NAMLEN(dirent) strlen((dirent)->d_name)
202#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#include <direct.h>
205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000218#endif
219#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <direct.h>
223#include <io.h>
224#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000225#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000227#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000229#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000230#else /* 16-bit Windows */
231#include <dos.h>
232#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000233#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235
Guido van Rossumd48f2521997-12-05 22:19:34 +0000236#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000239
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000240#ifdef UNION_WAIT
241/* Emulate some macros on systems that have a union instead of macros */
242
243#ifndef WIFEXITED
244#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
245#endif
246
247#ifndef WEXITSTATUS
248#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
249#endif
250
251#ifndef WTERMSIG
252#define WTERMSIG(u_wait) ((u_wait).w_termsig)
253#endif
254
255#endif /* UNION_WAIT */
256
Greg Wardb48bc172000-03-01 21:51:56 +0000257/* Don't use the "_r" form if we don't need it (also, won't have a
258 prototype for it, at least on Solaris -- maybe others as well?). */
259#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
260#define USE_CTERMID_R
261#endif
262
263#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
264#define USE_TMPNAM_R
265#endif
266
Fred Drake699f3522000-06-29 21:12:41 +0000267/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000268#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000269#ifdef MS_WIN64
270# define STAT _stati64
271# define FSTAT _fstati64
272# define STRUCT_STAT struct _stati64
273#else
274# define STAT stat
275# define FSTAT fstat
276# define STRUCT_STAT struct stat
277#endif
278
279
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280/* Return a dictionary corresponding to the POSIX environment table */
281
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000282#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000284#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285
Barry Warsaw53699e91996-12-10 23:23:01 +0000286static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000287convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288{
Barry Warsaw53699e91996-12-10 23:23:01 +0000289 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000291 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 if (d == NULL)
293 return NULL;
294 if (environ == NULL)
295 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000296 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000298 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000299 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 char *p = strchr(*e, '=');
301 if (p == NULL)
302 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000303 k = PyString_FromStringAndSize(*e, (int)(p-*e));
304 if (k == NULL) {
305 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000307 }
308 v = PyString_FromString(p+1);
309 if (v == NULL) {
310 PyErr_Clear();
311 Py_DECREF(k);
312 continue;
313 }
314 if (PyDict_GetItem(d, k) == NULL) {
315 if (PyDict_SetItem(d, k, v) != 0)
316 PyErr_Clear();
317 }
318 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000319 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000320 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000321#if defined(PYOS_OS2)
322 {
323 APIRET rc;
324 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
325
326 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000327 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000328 PyObject *v = PyString_FromString(buffer);
329 PyDict_SetItemString(d, "BEGINLIBPATH", v);
330 Py_DECREF(v);
331 }
332 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
333 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
334 PyObject *v = PyString_FromString(buffer);
335 PyDict_SetItemString(d, "ENDLIBPATH", v);
336 Py_DECREF(v);
337 }
338 }
339#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000340 return d;
341}
342
343
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344/* Set a POSIX-specific error from errno, and return NULL */
345
Barry Warsawd58d7641998-07-23 16:14:40 +0000346static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000347posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000348{
Barry Warsawca74da41999-02-09 19:31:45 +0000349 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000350}
Barry Warsawd58d7641998-07-23 16:14:40 +0000351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000352posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000353{
Barry Warsawca74da41999-02-09 19:31:45 +0000354 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000355}
356
Mark Hammondef8b6542001-05-13 08:04:26 +0000357static PyObject *
358posix_error_with_allocated_filename(char* name)
359{
360 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
361 PyMem_Free(name);
362 return rc;
363}
364
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000365#ifdef MS_WIN32
366static PyObject *
367win32_error(char* function, char* filename)
368{
Mark Hammond33a6da92000-08-15 00:46:38 +0000369 /* XXX We should pass the function name along in the future.
370 (_winreg.c also wants to pass the function name.)
371 This would however require an additional param to the
372 Windows error object, which is non-trivial.
373 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000374 errno = GetLastError();
375 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000376 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000377 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000378 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000379}
380#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000381
Guido van Rossumd48f2521997-12-05 22:19:34 +0000382#if defined(PYOS_OS2)
383/**********************************************************************
384 * Helper Function to Trim and Format OS/2 Messages
385 **********************************************************************/
386 static void
387os2_formatmsg(char *msgbuf, int msglen, char *reason)
388{
389 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
390
391 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
392 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
393
394 while (lastc > msgbuf && isspace(*lastc))
395 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
396 }
397
398 /* Add Optional Reason Text */
399 if (reason) {
400 strcat(msgbuf, " : ");
401 strcat(msgbuf, reason);
402 }
403}
404
405/**********************************************************************
406 * Decode an OS/2 Operating System Error Code
407 *
408 * A convenience function to lookup an OS/2 error code and return a
409 * text message we can use to raise a Python exception.
410 *
411 * Notes:
412 * The messages for errors returned from the OS/2 kernel reside in
413 * the file OSO001.MSG in the \OS2 directory hierarchy.
414 *
415 **********************************************************************/
416 static char *
417os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
418{
419 APIRET rc;
420 ULONG msglen;
421
422 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
423 Py_BEGIN_ALLOW_THREADS
424 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
425 errorcode, "oso001.msg", &msglen);
426 Py_END_ALLOW_THREADS
427
428 if (rc == NO_ERROR)
429 os2_formatmsg(msgbuf, msglen, reason);
430 else
431 sprintf(msgbuf, "unknown OS error #%d", errorcode);
432
433 return msgbuf;
434}
435
436/* Set an OS/2-specific error and return NULL. OS/2 kernel
437 errors are not in a global variable e.g. 'errno' nor are
438 they congruent with posix error numbers. */
439
440static PyObject * os2_error(int code)
441{
442 char text[1024];
443 PyObject *v;
444
445 os2_strerror(text, sizeof(text), code, "");
446
447 v = Py_BuildValue("(is)", code, text);
448 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000449 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000450 Py_DECREF(v);
451 }
452 return NULL; /* Signal to Python that an Exception is Pending */
453}
454
455#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000456
457/* POSIX generic methods */
458
Barry Warsaw53699e91996-12-10 23:23:01 +0000459static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000460posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000461{
462 int fd;
463 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000464 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000465 return NULL;
466 Py_BEGIN_ALLOW_THREADS
467 res = (*func)(fd);
468 Py_END_ALLOW_THREADS
469 if (res < 0)
470 return posix_error();
471 Py_INCREF(Py_None);
472 return Py_None;
473}
474
475
476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000477posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000478{
Mark Hammondef8b6542001-05-13 08:04:26 +0000479 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000480 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000481 if (!PyArg_ParseTuple(args, format,
482 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000484 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000486 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000487 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000488 return posix_error_with_allocated_filename(path1);
489 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000490 Py_INCREF(Py_None);
491 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492}
493
Barry Warsaw53699e91996-12-10 23:23:01 +0000494static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000495posix_2str(PyObject *args, char *format,
496 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497{
Mark Hammondef8b6542001-05-13 08:04:26 +0000498 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000499 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000500 if (!PyArg_ParseTuple(args, format,
501 Py_FileSystemDefaultEncoding, &path1,
502 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000503 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000504 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000505 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000506 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000507 PyMem_Free(path1);
508 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000509 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000510 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000512 Py_INCREF(Py_None);
513 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514}
515
Fred Drake699f3522000-06-29 21:12:41 +0000516/* pack a system stat C structure into the Python stat tuple
517 (used by posix_stat() and posix_fstat()) */
518static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000519_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000520{
521 PyObject *v = PyTuple_New(10);
522 if (v == NULL)
523 return NULL;
524
525 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
526#ifdef HAVE_LARGEFILE_SUPPORT
527 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
528#else
529 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
530#endif
531#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
532 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
533#else
534 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
535#endif
536 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
537 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
538 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
539#ifdef HAVE_LARGEFILE_SUPPORT
540 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
541#else
542 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
543#endif
544#if SIZEOF_TIME_T > SIZEOF_LONG
545 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
546 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
547 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
548#else
549 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
550 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
551 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
552#endif
553
554 if (PyErr_Occurred()) {
555 Py_DECREF(v);
556 return NULL;
557 }
558
559 return v;
560}
561
562
Barry Warsaw53699e91996-12-10 23:23:01 +0000563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000564posix_do_stat(PyObject *self, PyObject *args, char *format,
565 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000566{
Fred Drake699f3522000-06-29 21:12:41 +0000567 STRUCT_STAT st;
Mark Hammondef8b6542001-05-13 08:04:26 +0000568 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000569 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000570
571#ifdef MS_WIN32
572 int pathlen;
573 char pathcopy[MAX_PATH];
574#endif /* MS_WIN32 */
575
Mark Hammondef8b6542001-05-13 08:04:26 +0000576 if (!PyArg_ParseTuple(args, format,
577 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000578 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000579
580#ifdef MS_WIN32
581 pathlen = strlen(path);
582 /* the library call can blow up if the file name is too long! */
583 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000584 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000585 errno = ENAMETOOLONG;
586 return posix_error();
587 }
588
589 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000590 /* exception for specific or current drive root */
591 if (!((pathlen == 1) ||
592 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000593 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000594 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000595 {
596 strncpy(pathcopy, path, pathlen);
597 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
598 path = pathcopy;
599 }
600 }
601#endif /* MS_WIN32 */
602
Barry Warsaw53699e91996-12-10 23:23:01 +0000603 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000604 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000605 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000606 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000607 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000608
Mark Hammondef8b6542001-05-13 08:04:26 +0000609 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000610 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000611}
612
613
614/* POSIX methods */
615
Guido van Rossum94f6f721999-01-06 18:42:14 +0000616static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000617"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000618Test for access to a file.";
619
620static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000621posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000622{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000623 char *path;
624 int mode;
625 int res;
626
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000627 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000628 return NULL;
629 Py_BEGIN_ALLOW_THREADS
630 res = access(path, mode);
631 Py_END_ALLOW_THREADS
632 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000633}
634
Guido van Rossumd371ff11999-01-25 16:12:23 +0000635#ifndef F_OK
636#define F_OK 0
637#endif
638#ifndef R_OK
639#define R_OK 4
640#endif
641#ifndef W_OK
642#define W_OK 2
643#endif
644#ifndef X_OK
645#define X_OK 1
646#endif
647
648#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000649static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000650"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000651Return the name of the terminal device connected to 'fd'.";
652
653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000654posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000655{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000656 int id;
657 char *ret;
658
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000659 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000660 return NULL;
661
Guido van Rossum94f6f721999-01-06 18:42:14 +0000662 ret = ttyname(id);
663 if (ret == NULL)
664 return(posix_error());
665 return(PyString_FromString(ret));
666}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000667#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000668
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000669#ifdef HAVE_CTERMID
670static char posix_ctermid__doc__[] =
671"ctermid() -> String\n\
672Return the name of the controlling terminal for this process.";
673
674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000675posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000676{
677 char *ret;
678 char buffer[L_ctermid];
679
680 if (!PyArg_ParseTuple(args, ":ctermid"))
681 return NULL;
682
Greg Wardb48bc172000-03-01 21:51:56 +0000683#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000684 ret = ctermid_r(buffer);
685#else
686 ret = ctermid(buffer);
687#endif
688 if (ret == NULL)
689 return(posix_error());
690 return(PyString_FromString(buffer));
691}
692#endif
693
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000694static char posix_chdir__doc__[] =
695"chdir(path) -> None\n\
696Change the current working directory to the specified path.";
697
Barry Warsaw53699e91996-12-10 23:23:01 +0000698static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000699posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000700{
Mark Hammondef8b6542001-05-13 08:04:26 +0000701 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000702}
703
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000704
705static char posix_chmod__doc__[] =
706"chmod(path, mode) -> None\n\
707Change the access permissions of a file.";
708
Barry Warsaw53699e91996-12-10 23:23:01 +0000709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000710posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000711{
Mark Hammondef8b6542001-05-13 08:04:26 +0000712 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000713 int i;
714 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000715 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
716 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000717 return NULL;
718 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000719 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000720 Py_END_ALLOW_THREADS
721 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000722 return posix_error_with_allocated_filename(path);
723 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000724 Py_INCREF(Py_None);
725 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000726}
727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000728
Guido van Rossum21142a01999-01-08 21:05:37 +0000729#ifdef HAVE_FSYNC
730static char posix_fsync__doc__[] =
731"fsync(fildes) -> None\n\
732force write of file with filedescriptor to disk.";
733
734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000735posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000736{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000737 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000738}
739#endif /* HAVE_FSYNC */
740
741#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000742
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000743#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000744extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
745#endif
746
Guido van Rossum21142a01999-01-08 21:05:37 +0000747static char posix_fdatasync__doc__[] =
748"fdatasync(fildes) -> None\n\
749force write of file with filedescriptor to disk.\n\
750 does not force update of metadata.";
751
752static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000753posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000754{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000755 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000756}
757#endif /* HAVE_FDATASYNC */
758
759
Fredrik Lundh10723342000-07-10 16:38:09 +0000760#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000761static char posix_chown__doc__[] =
762"chown(path, uid, gid) -> None\n\
763Change the owner and group id of path to the numeric uid and gid.";
764
Barry Warsaw53699e91996-12-10 23:23:01 +0000765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000766posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000767{
Mark Hammondef8b6542001-05-13 08:04:26 +0000768 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000769 int uid, gid;
770 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000771 if (!PyArg_ParseTuple(args, "etii:chown",
772 Py_FileSystemDefaultEncoding, &path,
773 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000774 return NULL;
775 Py_BEGIN_ALLOW_THREADS
776 res = chown(path, (uid_t) uid, (gid_t) gid);
777 Py_END_ALLOW_THREADS
778 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000779 return posix_error_with_allocated_filename(path);
780 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000781 Py_INCREF(Py_None);
782 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000783}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000784#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000786
Guido van Rossum36bc6801995-06-14 22:54:23 +0000787#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000788static char posix_getcwd__doc__[] =
789"getcwd() -> path\n\
790Return a string representing the current working directory.";
791
Barry Warsaw53699e91996-12-10 23:23:01 +0000792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000793posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000794{
795 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000796 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000797 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000798 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000799 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000800 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000801 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000802 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000803 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000804 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000806#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000808
Guido van Rossumb6775db1994-08-01 11:34:53 +0000809#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000810static char posix_link__doc__[] =
811"link(src, dst) -> None\n\
812Create a hard link to a file.";
813
Barry Warsaw53699e91996-12-10 23:23:01 +0000814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000815posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000816{
Mark Hammondef8b6542001-05-13 08:04:26 +0000817 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000819#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000820
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000821
822static char posix_listdir__doc__[] =
823"listdir(path) -> list_of_strings\n\
824Return a list containing the names of the entries in the directory.\n\
825\n\
826 path: path of directory to list\n\
827\n\
828The list is in arbitrary order. It does not include the special\n\
829entries '.' and '..' even if they are present in the directory.";
830
Barry Warsaw53699e91996-12-10 23:23:01 +0000831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000832posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000833{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000834 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000835 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000836#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000837
Barry Warsaw53699e91996-12-10 23:23:01 +0000838 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000839 HANDLE hFindFile;
840 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000841 /* MAX_PATH characters could mean a bigger encoded string */
842 char namebuf[MAX_PATH*2+5];
843 char *bufptr = namebuf;
844 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000845 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000846
Mark Hammondef8b6542001-05-13 08:04:26 +0000847 if (!PyArg_ParseTuple(args, "et#:listdir",
848 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000849 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000850 ch = namebuf[len-1];
851 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000852 namebuf[len++] = '/';
853 strcpy(namebuf + len, "*.*");
854
Barry Warsaw53699e91996-12-10 23:23:01 +0000855 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000856 return NULL;
857
858 hFindFile = FindFirstFile(namebuf, &FileData);
859 if (hFindFile == INVALID_HANDLE_VALUE) {
860 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000861 if (errno == ERROR_FILE_NOT_FOUND)
862 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000863 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000864 }
865 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000866 if (FileData.cFileName[0] == '.' &&
867 (FileData.cFileName[1] == '\0' ||
868 FileData.cFileName[1] == '.' &&
869 FileData.cFileName[2] == '\0'))
870 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000871 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000872 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000873 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000874 d = NULL;
875 break;
876 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000877 if (PyList_Append(d, v) != 0) {
878 Py_DECREF(v);
879 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000880 d = NULL;
881 break;
882 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000883 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000884 } while (FindNextFile(hFindFile, &FileData) == TRUE);
885
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000886 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +0000887 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000888
889 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000890
Tim Peters0bb44a42000-09-15 07:44:49 +0000891#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000892
893#ifndef MAX_PATH
894#define MAX_PATH 250
895#endif
896 char *name, *pt;
897 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000898 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000899 char namebuf[MAX_PATH+5];
900 struct _find_t ep;
901
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000902 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000903 return NULL;
904 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000905 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000906 return NULL;
907 }
908 strcpy(namebuf, name);
909 for (pt = namebuf; *pt; pt++)
910 if (*pt == '/')
911 *pt = '\\';
912 if (namebuf[len-1] != '\\')
913 namebuf[len++] = '\\';
914 strcpy(namebuf + len, "*.*");
915
Barry Warsaw53699e91996-12-10 23:23:01 +0000916 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000917 return NULL;
918
919 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000920 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
921 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000922 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000923 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000924 }
925 do {
926 if (ep.name[0] == '.' &&
927 (ep.name[1] == '\0' ||
928 ep.name[1] == '.' &&
929 ep.name[2] == '\0'))
930 continue;
931 strcpy(namebuf, ep.name);
932 for (pt = namebuf; *pt; pt++)
933 if (isupper(*pt))
934 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000935 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000936 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000937 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000938 d = NULL;
939 break;
940 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000941 if (PyList_Append(d, v) != 0) {
942 Py_DECREF(v);
943 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000944 d = NULL;
945 break;
946 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000947 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000948 } while (_dos_findnext(&ep) == 0);
949
950 return d;
951
Tim Peters0bb44a42000-09-15 07:44:49 +0000952#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000953
954#ifndef MAX_PATH
955#define MAX_PATH CCHMAXPATH
956#endif
957 char *name, *pt;
958 int len;
959 PyObject *d, *v;
960 char namebuf[MAX_PATH+5];
961 HDIR hdir = 1;
962 ULONG srchcnt = 1;
963 FILEFINDBUF3 ep;
964 APIRET rc;
965
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000966 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000967 return NULL;
968 if (len >= MAX_PATH) {
969 PyErr_SetString(PyExc_ValueError, "path too long");
970 return NULL;
971 }
972 strcpy(namebuf, name);
973 for (pt = namebuf; *pt; pt++)
974 if (*pt == '/')
975 *pt = '\\';
976 if (namebuf[len-1] != '\\')
977 namebuf[len++] = '\\';
978 strcpy(namebuf + len, "*.*");
979
980 if ((d = PyList_New(0)) == NULL)
981 return NULL;
982
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000983 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
984 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000985 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000986 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
987 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
988 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000989
990 if (rc != NO_ERROR) {
991 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000992 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000993 }
994
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000995 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000996 do {
997 if (ep.achName[0] == '.'
998 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000999 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001000
1001 strcpy(namebuf, ep.achName);
1002
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001003 /* Leave Case of Name Alone -- In Native Form */
1004 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001005
1006 v = PyString_FromString(namebuf);
1007 if (v == NULL) {
1008 Py_DECREF(d);
1009 d = NULL;
1010 break;
1011 }
1012 if (PyList_Append(d, v) != 0) {
1013 Py_DECREF(v);
1014 Py_DECREF(d);
1015 d = NULL;
1016 break;
1017 }
1018 Py_DECREF(v);
1019 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1020 }
1021
1022 return d;
1023#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001024
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001025 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001026 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001027 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001028 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001029 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001030 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001031 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001032 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001033 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001034 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001035 closedir(dirp);
1036 return NULL;
1037 }
1038 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001039 if (ep->d_name[0] == '.' &&
1040 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001041 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001042 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001043 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001044 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001045 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001046 d = NULL;
1047 break;
1048 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001049 if (PyList_Append(d, v) != 0) {
1050 Py_DECREF(v);
1051 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001052 d = NULL;
1053 break;
1054 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001055 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001056 }
1057 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001058
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001059 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001060
Tim Peters0bb44a42000-09-15 07:44:49 +00001061#endif /* which OS */
1062} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001063
Mark Hammondef8b6542001-05-13 08:04:26 +00001064#ifdef MS_WIN32
1065/* A helper function for abspath on win32 */
1066static PyObject *
1067posix__getfullpathname(PyObject *self, PyObject *args)
1068{
1069 /* assume encoded strings wont more than double no of chars */
1070 char inbuf[MAX_PATH*2];
1071 char *inbufp = inbuf;
1072 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1073 char outbuf[MAX_PATH*2];
1074 char *temp;
1075 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1076 Py_FileSystemDefaultEncoding, &inbufp,
1077 &insize))
1078 return NULL;
1079 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1080 outbuf, &temp))
1081 return win32_error("GetFullPathName", inbuf);
1082 return PyString_FromString(outbuf);
1083} /* end of posix__getfullpathname */
1084#endif /* MS_WIN32 */
1085
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001086static char posix_mkdir__doc__[] =
1087"mkdir(path [, mode=0777]) -> None\n\
1088Create a directory.";
1089
Barry Warsaw53699e91996-12-10 23:23:01 +00001090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001091posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001092{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001093 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001094 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001095 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001096 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1097 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001098 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001099 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001100#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001101 res = mkdir(path);
1102#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001103 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001104#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001105 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001106 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001107 return posix_error_with_allocated_filename(path);
1108 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001109 Py_INCREF(Py_None);
1110 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001111}
1112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001113
Guido van Rossumb6775db1994-08-01 11:34:53 +00001114#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001115static char posix_nice__doc__[] =
1116"nice(inc) -> new_priority\n\
1117Decrease the priority of process and return new priority.";
1118
Barry Warsaw53699e91996-12-10 23:23:01 +00001119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001120posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001121{
1122 int increment, value;
1123
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001124 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001125 return NULL;
1126 value = nice(increment);
1127 if (value == -1)
1128 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001129 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001130}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001131#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001133
1134static char posix_rename__doc__[] =
1135"rename(old, new) -> None\n\
1136Rename a file or directory.";
1137
Barry Warsaw53699e91996-12-10 23:23:01 +00001138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001139posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001140{
Mark Hammondef8b6542001-05-13 08:04:26 +00001141 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142}
1143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001144
1145static char posix_rmdir__doc__[] =
1146"rmdir(path) -> None\n\
1147Remove a directory.";
1148
Barry Warsaw53699e91996-12-10 23:23:01 +00001149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001150posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001151{
Mark Hammondef8b6542001-05-13 08:04:26 +00001152 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153}
1154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001155
1156static char posix_stat__doc__[] =
1157"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1158Perform a stat system call on the given path.";
1159
Barry Warsaw53699e91996-12-10 23:23:01 +00001160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001161posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162{
Mark Hammondef8b6542001-05-13 08:04:26 +00001163 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001164}
1165
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001166
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001167#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001168static char posix_system__doc__[] =
1169"system(command) -> exit_status\n\
1170Execute the command (a string) in a subshell.";
1171
Barry Warsaw53699e91996-12-10 23:23:01 +00001172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001173posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001174{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001175 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001176 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001177 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001179 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001180 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001181 Py_END_ALLOW_THREADS
1182 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001183}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001184#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001186
1187static char posix_umask__doc__[] =
1188"umask(new_mask) -> old_mask\n\
1189Set the current numeric umask and return the previous umask.";
1190
Barry Warsaw53699e91996-12-10 23:23:01 +00001191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001192posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001193{
1194 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001195 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001196 return NULL;
1197 i = umask(i);
1198 if (i < 0)
1199 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001200 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001201}
1202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001203
1204static char posix_unlink__doc__[] =
1205"unlink(path) -> None\n\
1206Remove a file (same as remove(path)).";
1207
1208static char posix_remove__doc__[] =
1209"remove(path) -> None\n\
1210Remove a file (same as unlink(path)).";
1211
Barry Warsaw53699e91996-12-10 23:23:01 +00001212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001213posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214{
Mark Hammondef8b6542001-05-13 08:04:26 +00001215 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001216}
1217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001218
Guido van Rossumb6775db1994-08-01 11:34:53 +00001219#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001220static char posix_uname__doc__[] =
1221"uname() -> (sysname, nodename, release, version, machine)\n\
1222Return a tuple identifying the current operating system.";
1223
Barry Warsaw53699e91996-12-10 23:23:01 +00001224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001225posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001226{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001227 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001228 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001229 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001230 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001231 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001232 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001233 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001234 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001235 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001236 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001237 u.sysname,
1238 u.nodename,
1239 u.release,
1240 u.version,
1241 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001242}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001243#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001245
1246static char posix_utime__doc__[] =
1247"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001248utime(path, None) -> None\n\
1249Set the access and modified time of the file to the given values. If the\n\
1250second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001251
Barry Warsaw53699e91996-12-10 23:23:01 +00001252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001253posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001255 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001256 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001257 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001258 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001259
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001260/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001261#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001262 struct utimbuf buf;
1263#define ATIME buf.actime
1264#define MTIME buf.modtime
1265#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001266#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001267 time_t buf[2];
1268#define ATIME buf[0]
1269#define MTIME buf[1]
1270#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001271#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001272
Barry Warsaw3cef8562000-05-01 16:17:24 +00001273 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001274 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001275 if (arg == Py_None) {
1276 /* optional time values not given */
1277 Py_BEGIN_ALLOW_THREADS
1278 res = utime(path, NULL);
1279 Py_END_ALLOW_THREADS
1280 }
1281 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1282 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001283 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001284 return NULL;
1285 }
1286 else {
1287 ATIME = atime;
1288 MTIME = mtime;
1289 Py_BEGIN_ALLOW_THREADS
1290 res = utime(path, UTIME_ARG);
1291 Py_END_ALLOW_THREADS
1292 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001293 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001294 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001295 Py_INCREF(Py_None);
1296 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001297#undef UTIME_ARG
1298#undef ATIME
1299#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001300}
1301
Guido van Rossum85e3b011991-06-03 12:42:10 +00001302
Guido van Rossum3b066191991-06-04 19:40:25 +00001303/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001304
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001305static char posix__exit__doc__[] =
1306"_exit(status)\n\
1307Exit to the system with specified status, without normal exit processing.";
1308
Barry Warsaw53699e91996-12-10 23:23:01 +00001309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001310posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001311{
1312 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001313 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001314 return NULL;
1315 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001316 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001317}
1318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001319
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001320#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001321static char posix_execv__doc__[] =
1322"execv(path, args)\n\
1323Execute an executable path with arguments, replacing current process.\n\
1324\n\
1325 path: path of executable file\n\
1326 args: tuple or list of strings";
1327
Barry Warsaw53699e91996-12-10 23:23:01 +00001328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001329posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001330{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001331 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001332 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001333 char **argvlist;
1334 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001335 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001336
Guido van Rossum89b33251993-10-22 14:26:06 +00001337 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001338 argv is a list or tuple of strings. */
1339
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001340 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001341 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001342 if (PyList_Check(argv)) {
1343 argc = PyList_Size(argv);
1344 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001345 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001346 else if (PyTuple_Check(argv)) {
1347 argc = PyTuple_Size(argv);
1348 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001349 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001350 else {
Fred Drake661ea262000-10-24 19:57:45 +00001351 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001352 return NULL;
1353 }
1354
1355 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001356 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001357 return NULL;
1358 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001359
Barry Warsaw53699e91996-12-10 23:23:01 +00001360 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001361 if (argvlist == NULL)
1362 return NULL;
1363 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001364 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1365 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001366 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001367 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001368 return NULL;
1369
Guido van Rossum85e3b011991-06-03 12:42:10 +00001370 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001371 }
1372 argvlist[argc] = NULL;
1373
Guido van Rossumb6775db1994-08-01 11:34:53 +00001374#ifdef BAD_EXEC_PROTOTYPES
1375 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001376#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001377 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001378#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001379
Guido van Rossum85e3b011991-06-03 12:42:10 +00001380 /* If we get here it's definitely an error */
1381
Barry Warsaw53699e91996-12-10 23:23:01 +00001382 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001383 return posix_error();
1384}
1385
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001386
1387static char posix_execve__doc__[] =
1388"execve(path, args, env)\n\
1389Execute a path with arguments and environment, replacing current process.\n\
1390\n\
1391 path: path of executable file\n\
1392 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001393 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001394
Barry Warsaw53699e91996-12-10 23:23:01 +00001395static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001396posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001397{
1398 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001399 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001400 char **argvlist;
1401 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001402 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001403 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001404 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001405
1406 /* execve has three arguments: (path, argv, env), where
1407 argv is a list or tuple of strings and env is a dictionary
1408 like posix.environ. */
1409
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001410 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001411 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001412 if (PyList_Check(argv)) {
1413 argc = PyList_Size(argv);
1414 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001415 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001416 else if (PyTuple_Check(argv)) {
1417 argc = PyTuple_Size(argv);
1418 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001419 }
1420 else {
Fred Drake661ea262000-10-24 19:57:45 +00001421 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001422 return NULL;
1423 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001424 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001425 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001426 return NULL;
1427 }
1428
Guido van Rossum50422b42000-04-26 20:34:28 +00001429 if (argc == 0) {
1430 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001431 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001432 return NULL;
1433 }
1434
Barry Warsaw53699e91996-12-10 23:23:01 +00001435 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001436 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001437 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001438 return NULL;
1439 }
1440 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001441 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001442 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001443 &argvlist[i]))
1444 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001445 goto fail_1;
1446 }
1447 }
1448 argvlist[argc] = NULL;
1449
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001450 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001451 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001452 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001453 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001454 goto fail_1;
1455 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001456 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001457 keys = PyMapping_Keys(env);
1458 vals = PyMapping_Values(env);
1459 if (!keys || !vals)
1460 goto fail_2;
1461
1462 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001463 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001464
1465 key = PyList_GetItem(keys, pos);
1466 val = PyList_GetItem(vals, pos);
1467 if (!key || !val)
1468 goto fail_2;
1469
Fred Drake661ea262000-10-24 19:57:45 +00001470 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1471 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001472 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001473 goto fail_2;
1474 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001475
1476#if defined(PYOS_OS2)
1477 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1478 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1479#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001480 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001481 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001482 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001483 goto fail_2;
1484 }
1485 sprintf(p, "%s=%s", k, v);
1486 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001487#if defined(PYOS_OS2)
1488 }
1489#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001490 }
1491 envlist[envc] = 0;
1492
Guido van Rossumb6775db1994-08-01 11:34:53 +00001493
1494#ifdef BAD_EXEC_PROTOTYPES
1495 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001496#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001497 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001498#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001499
1500 /* If we get here it's definitely an error */
1501
1502 (void) posix_error();
1503
1504 fail_2:
1505 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001506 PyMem_DEL(envlist[envc]);
1507 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001508 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001509 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001510 Py_XDECREF(vals);
1511 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001512 return NULL;
1513}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001514#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001516
Guido van Rossuma1065681999-01-25 23:20:23 +00001517#ifdef HAVE_SPAWNV
1518static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001519"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001520Execute an executable path with arguments, replacing current process.\n\
1521\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001522 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001523 path: path of executable file\n\
1524 args: tuple or list of strings";
1525
1526static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001527posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001528{
1529 char *path;
1530 PyObject *argv;
1531 char **argvlist;
1532 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001533 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001534 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001535
1536 /* spawnv has three arguments: (mode, path, argv), where
1537 argv is a list or tuple of strings. */
1538
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001539 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001540 return NULL;
1541 if (PyList_Check(argv)) {
1542 argc = PyList_Size(argv);
1543 getitem = PyList_GetItem;
1544 }
1545 else if (PyTuple_Check(argv)) {
1546 argc = PyTuple_Size(argv);
1547 getitem = PyTuple_GetItem;
1548 }
1549 else {
Fred Drake661ea262000-10-24 19:57:45 +00001550 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001551 return NULL;
1552 }
1553
1554 argvlist = PyMem_NEW(char *, argc+1);
1555 if (argvlist == NULL)
1556 return NULL;
1557 for (i = 0; i < argc; i++) {
1558 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1559 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001560 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001561 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001562 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001563 }
1564 }
1565 argvlist[argc] = NULL;
1566
Guido van Rossum246bc171999-02-01 23:54:31 +00001567 if (mode == _OLD_P_OVERLAY)
1568 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001569 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001570
1571 PyMem_DEL(argvlist);
1572
Fred Drake699f3522000-06-29 21:12:41 +00001573 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001574 return posix_error();
1575 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001576#if SIZEOF_LONG == SIZEOF_VOID_P
1577 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001578#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001579 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001580#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001581}
1582
1583
1584static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001585"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001586Execute a path with arguments and environment, replacing current process.\n\
1587\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001588 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001589 path: path of executable file\n\
1590 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001591 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001592
1593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001594posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001595{
1596 char *path;
1597 PyObject *argv, *env;
1598 char **argvlist;
1599 char **envlist;
1600 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1601 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001602 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001603 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001604
1605 /* spawnve has four arguments: (mode, path, argv, env), where
1606 argv is a list or tuple of strings and env is a dictionary
1607 like posix.environ. */
1608
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001609 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001610 return NULL;
1611 if (PyList_Check(argv)) {
1612 argc = PyList_Size(argv);
1613 getitem = PyList_GetItem;
1614 }
1615 else if (PyTuple_Check(argv)) {
1616 argc = PyTuple_Size(argv);
1617 getitem = PyTuple_GetItem;
1618 }
1619 else {
Fred Drake661ea262000-10-24 19:57:45 +00001620 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001621 return NULL;
1622 }
1623 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001624 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001625 return NULL;
1626 }
1627
1628 argvlist = PyMem_NEW(char *, argc+1);
1629 if (argvlist == NULL) {
1630 PyErr_NoMemory();
1631 return NULL;
1632 }
1633 for (i = 0; i < argc; i++) {
1634 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001635 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001636 &argvlist[i]))
1637 {
1638 goto fail_1;
1639 }
1640 }
1641 argvlist[argc] = NULL;
1642
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001643 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001644 envlist = PyMem_NEW(char *, i + 1);
1645 if (envlist == NULL) {
1646 PyErr_NoMemory();
1647 goto fail_1;
1648 }
1649 envc = 0;
1650 keys = PyMapping_Keys(env);
1651 vals = PyMapping_Values(env);
1652 if (!keys || !vals)
1653 goto fail_2;
1654
1655 for (pos = 0; pos < i; pos++) {
1656 char *p, *k, *v;
1657
1658 key = PyList_GetItem(keys, pos);
1659 val = PyList_GetItem(vals, pos);
1660 if (!key || !val)
1661 goto fail_2;
1662
Fred Drake661ea262000-10-24 19:57:45 +00001663 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1664 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001665 {
1666 goto fail_2;
1667 }
1668 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1669 if (p == NULL) {
1670 PyErr_NoMemory();
1671 goto fail_2;
1672 }
1673 sprintf(p, "%s=%s", k, v);
1674 envlist[envc++] = p;
1675 }
1676 envlist[envc] = 0;
1677
Guido van Rossum246bc171999-02-01 23:54:31 +00001678 if (mode == _OLD_P_OVERLAY)
1679 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001680 spawnval = _spawnve(mode, path, argvlist, envlist);
1681 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001682 (void) posix_error();
1683 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001684#if SIZEOF_LONG == SIZEOF_VOID_P
1685 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001686#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001687 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001688#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001689
1690 fail_2:
1691 while (--envc >= 0)
1692 PyMem_DEL(envlist[envc]);
1693 PyMem_DEL(envlist);
1694 fail_1:
1695 PyMem_DEL(argvlist);
1696 Py_XDECREF(vals);
1697 Py_XDECREF(keys);
1698 return res;
1699}
1700#endif /* HAVE_SPAWNV */
1701
1702
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001703#ifdef HAVE_FORK1
1704static char posix_fork1__doc__[] =
1705"fork1() -> pid\n\
1706Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1707\n\
1708Return 0 to child process and PID of child to parent process.";
1709
1710static PyObject *
1711posix_fork1(self, args)
1712 PyObject *self;
1713 PyObject *args;
1714{
1715 int pid;
1716 if (!PyArg_ParseTuple(args, ":fork1"))
1717 return NULL;
1718 pid = fork1();
1719 if (pid == -1)
1720 return posix_error();
1721 PyOS_AfterFork();
1722 return PyInt_FromLong((long)pid);
1723}
1724#endif
1725
1726
Guido van Rossumad0ee831995-03-01 10:34:45 +00001727#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001728static char posix_fork__doc__[] =
1729"fork() -> pid\n\
1730Fork a child process.\n\
1731\n\
1732Return 0 to child process and PID of child to parent process.";
1733
Barry Warsaw53699e91996-12-10 23:23:01 +00001734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001735posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001736{
1737 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001738 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001739 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001740 pid = fork();
1741 if (pid == -1)
1742 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001743 if (pid == 0)
1744 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001745 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001746}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001747#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001748
Fred Drake8cef4cf2000-06-28 16:40:38 +00001749#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1750#ifdef HAVE_PTY_H
1751#include <pty.h>
1752#else
1753#ifdef HAVE_LIBUTIL_H
1754#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001755#endif /* HAVE_LIBUTIL_H */
1756#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001757#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001758
Thomas Wouters70c21a12000-07-14 14:28:33 +00001759#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001760static char posix_openpty__doc__[] =
1761"openpty() -> (master_fd, slave_fd)\n\
1762Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1763
1764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001765posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001766{
1767 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001768#ifndef HAVE_OPENPTY
1769 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001770#endif
1771
Fred Drake8cef4cf2000-06-28 16:40:38 +00001772 if (!PyArg_ParseTuple(args, ":openpty"))
1773 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001774
1775#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001776 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1777 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001778#else
1779 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1780 if (slave_name == NULL)
1781 return posix_error();
1782
1783 slave_fd = open(slave_name, O_RDWR);
1784 if (slave_fd < 0)
1785 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001786#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001787
Fred Drake8cef4cf2000-06-28 16:40:38 +00001788 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001789
Fred Drake8cef4cf2000-06-28 16:40:38 +00001790}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001791#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001792
1793#ifdef HAVE_FORKPTY
1794static char posix_forkpty__doc__[] =
1795"forkpty() -> (pid, master_fd)\n\
1796Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1797Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1798To both, return fd of newly opened pseudo-terminal.\n";
1799
1800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001801posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001802{
1803 int master_fd, pid;
1804
1805 if (!PyArg_ParseTuple(args, ":forkpty"))
1806 return NULL;
1807 pid = forkpty(&master_fd, NULL, NULL, NULL);
1808 if (pid == -1)
1809 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001810 if (pid == 0)
1811 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001812 return Py_BuildValue("(ii)", pid, master_fd);
1813}
1814#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001815
Guido van Rossumad0ee831995-03-01 10:34:45 +00001816#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001817static char posix_getegid__doc__[] =
1818"getegid() -> egid\n\
1819Return the current process's effective group id.";
1820
Barry Warsaw53699e91996-12-10 23:23:01 +00001821static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001822posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001823{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001824 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001825 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001826 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001827}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001828#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001830
Guido van Rossumad0ee831995-03-01 10:34:45 +00001831#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001832static char posix_geteuid__doc__[] =
1833"geteuid() -> euid\n\
1834Return the current process's effective user id.";
1835
Barry Warsaw53699e91996-12-10 23:23:01 +00001836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001837posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001838{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001839 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001840 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001841 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001842}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001843#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001844
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001845
Guido van Rossumad0ee831995-03-01 10:34:45 +00001846#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001847static char posix_getgid__doc__[] =
1848"getgid() -> gid\n\
1849Return the current process's group id.";
1850
Barry Warsaw53699e91996-12-10 23:23:01 +00001851static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001852posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001853{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001854 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001855 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001856 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001857}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001858#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001859
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001860
1861static char posix_getpid__doc__[] =
1862"getpid() -> pid\n\
1863Return the current process id";
1864
Barry Warsaw53699e91996-12-10 23:23:01 +00001865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001866posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001867{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001868 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001869 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001870 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001871}
1872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001873
Fred Drakec9680921999-12-13 16:37:25 +00001874#ifdef HAVE_GETGROUPS
1875static char posix_getgroups__doc__[] = "\
1876getgroups() -> list of group IDs\n\
1877Return list of supplemental group IDs for the process.";
1878
1879static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001880posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001881{
1882 PyObject *result = NULL;
1883
1884 if (PyArg_ParseTuple(args, ":getgroups")) {
1885#ifdef NGROUPS_MAX
1886#define MAX_GROUPS NGROUPS_MAX
1887#else
1888 /* defined to be 16 on Solaris7, so this should be a small number */
1889#define MAX_GROUPS 64
1890#endif
1891 gid_t grouplist[MAX_GROUPS];
1892 int n;
1893
1894 n = getgroups(MAX_GROUPS, grouplist);
1895 if (n < 0)
1896 posix_error();
1897 else {
1898 result = PyList_New(n);
1899 if (result != NULL) {
1900 PyObject *o;
1901 int i;
1902 for (i = 0; i < n; ++i) {
1903 o = PyInt_FromLong((long)grouplist[i]);
1904 if (o == NULL) {
1905 Py_DECREF(result);
1906 result = NULL;
1907 break;
1908 }
1909 PyList_SET_ITEM(result, i, o);
1910 }
1911 }
1912 }
1913 }
1914 return result;
1915}
1916#endif
1917
Guido van Rossumb6775db1994-08-01 11:34:53 +00001918#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001919static char posix_getpgrp__doc__[] =
1920"getpgrp() -> pgrp\n\
1921Return the current process group id.";
1922
Barry Warsaw53699e91996-12-10 23:23:01 +00001923static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001924posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001925{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001926 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001927 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001928#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001929 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001930#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001931 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001932#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001933}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001934#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001935
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001936
Guido van Rossumb6775db1994-08-01 11:34:53 +00001937#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001938static char posix_setpgrp__doc__[] =
1939"setpgrp() -> None\n\
1940Make this process a session leader.";
1941
Barry Warsaw53699e91996-12-10 23:23:01 +00001942static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001943posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001944{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001945 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001946 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001947#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001948 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001949#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001950 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001951#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001952 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001953 Py_INCREF(Py_None);
1954 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001955}
1956
Guido van Rossumb6775db1994-08-01 11:34:53 +00001957#endif /* HAVE_SETPGRP */
1958
Guido van Rossumad0ee831995-03-01 10:34:45 +00001959#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001960static char posix_getppid__doc__[] =
1961"getppid() -> ppid\n\
1962Return the parent's process id.";
1963
Barry Warsaw53699e91996-12-10 23:23:01 +00001964static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001965posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001966{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001967 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001968 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001969 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001970}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001971#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001972
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001973
Fred Drake12c6e2d1999-12-14 21:25:03 +00001974#ifdef HAVE_GETLOGIN
1975static char posix_getlogin__doc__[] = "\
1976getlogin() -> string\n\
1977Return the actual login name.";
1978
1979static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001980posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001981{
1982 PyObject *result = NULL;
1983
1984 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00001985 char *name;
1986 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001987
Fred Drakea30680b2000-12-06 21:24:28 +00001988 errno = 0;
1989 name = getlogin();
1990 if (name == NULL) {
1991 if (errno)
1992 posix_error();
1993 else
1994 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00001995 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00001996 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00001997 else
1998 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00001999 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002000 }
2001 return result;
2002}
2003#endif
2004
Guido van Rossumad0ee831995-03-01 10:34:45 +00002005#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002006static char posix_getuid__doc__[] =
2007"getuid() -> uid\n\
2008Return the current process's user id.";
2009
Barry Warsaw53699e91996-12-10 23:23:01 +00002010static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002011posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002012{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002013 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002014 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002015 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002016}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002017#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002019
Guido van Rossumad0ee831995-03-01 10:34:45 +00002020#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002021static char posix_kill__doc__[] =
2022"kill(pid, sig) -> None\n\
2023Kill a process with a signal.";
2024
Barry Warsaw53699e91996-12-10 23:23:01 +00002025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002026posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002027{
2028 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002029 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002030 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002031#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002032 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2033 APIRET rc;
2034 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002035 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002036
2037 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2038 APIRET rc;
2039 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002040 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002041
2042 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002043 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002044#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002045 if (kill(pid, sig) == -1)
2046 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002047#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002048 Py_INCREF(Py_None);
2049 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002050}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002051#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002052
Guido van Rossumc0125471996-06-28 18:55:32 +00002053#ifdef HAVE_PLOCK
2054
2055#ifdef HAVE_SYS_LOCK_H
2056#include <sys/lock.h>
2057#endif
2058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059static char posix_plock__doc__[] =
2060"plock(op) -> None\n\
2061Lock program segments into memory.";
2062
Barry Warsaw53699e91996-12-10 23:23:01 +00002063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002064posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002065{
2066 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002067 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002068 return NULL;
2069 if (plock(op) == -1)
2070 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002071 Py_INCREF(Py_None);
2072 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002073}
2074#endif
2075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002076
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002077#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002078static char posix_popen__doc__[] =
2079"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2080Open a pipe to/from a command returning a file object.";
2081
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002082#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002083static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002084async_system(const char *command)
2085{
2086 char *p, errormsg[256], args[1024];
2087 RESULTCODES rcodes;
2088 APIRET rc;
2089 char *shell = getenv("COMSPEC");
2090 if (!shell)
2091 shell = "cmd";
2092
2093 strcpy(args, shell);
2094 p = &args[ strlen(args)+1 ];
2095 strcpy(p, "/c ");
2096 strcat(p, command);
2097 p += strlen(p) + 1;
2098 *p = '\0';
2099
2100 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002101 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002102 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002103 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002104 &rcodes, shell);
2105 return rc;
2106}
2107
Guido van Rossumd48f2521997-12-05 22:19:34 +00002108static FILE *
2109popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002110{
2111 HFILE rhan, whan;
2112 FILE *retfd = NULL;
2113 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2114
Guido van Rossumd48f2521997-12-05 22:19:34 +00002115 if (rc != NO_ERROR) {
2116 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002117 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002118 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002119
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002120 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2121 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002122
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002123 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2124 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002125
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002126 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2127 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002128
2129 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002130 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002131 }
2132
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002133 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2134 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002135
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002136 close(oldfd); /* And Close Saved STDOUT Handle */
2137 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002138
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002139 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2140 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002141
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002142 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2143 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002144
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002145 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2146 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002147
2148 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002149 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002150 }
2151
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002152 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2153 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002154
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002155 close(oldfd); /* And Close Saved STDIN Handle */
2156 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002157
Guido van Rossumd48f2521997-12-05 22:19:34 +00002158 } else {
2159 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002160 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002161 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002162}
2163
2164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002165posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002166{
2167 char *name;
2168 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002169 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002170 FILE *fp;
2171 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002172 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002173 return NULL;
2174 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002175 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002176 Py_END_ALLOW_THREADS
2177 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002178 return os2_error(err);
2179
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002180 f = PyFile_FromFile(fp, name, mode, fclose);
2181 if (f != NULL)
2182 PyFile_SetBufSize(f, bufsize);
2183 return f;
2184}
2185
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002186#elif defined(MS_WIN32)
2187
2188/*
2189 * Portable 'popen' replacement for Win32.
2190 *
2191 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2192 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002193 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002194 */
2195
2196#include <malloc.h>
2197#include <io.h>
2198#include <fcntl.h>
2199
2200/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2201#define POPEN_1 1
2202#define POPEN_2 2
2203#define POPEN_3 3
2204#define POPEN_4 4
2205
2206static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002207static int _PyPclose(FILE *file);
2208
2209/*
2210 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002211 * for use when retrieving the process exit code. See _PyPclose() below
2212 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002213 */
2214static PyObject *_PyPopenProcs = NULL;
2215
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002216
2217/* popen that works from a GUI.
2218 *
2219 * The result of this function is a pipe (file) connected to the
2220 * processes stdin or stdout, depending on the requested mode.
2221 */
2222
2223static PyObject *
2224posix_popen(PyObject *self, PyObject *args)
2225{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002226 PyObject *f, *s;
2227 int tm = 0;
2228
2229 char *cmdstring;
2230 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002231 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002232 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002233 return NULL;
2234
2235 s = PyTuple_New(0);
2236
2237 if (*mode == 'r')
2238 tm = _O_RDONLY;
2239 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002240 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002241 return NULL;
2242 } else
2243 tm = _O_WRONLY;
2244
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002245 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002246 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002247 return NULL;
2248 }
2249
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002250 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002251 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002252 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002253 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002254 else
2255 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2256
2257 return f;
2258}
2259
2260/* Variation on win32pipe.popen
2261 *
2262 * The result of this function is a pipe (file) connected to the
2263 * process's stdin, and a pipe connected to the process's stdout.
2264 */
2265
2266static PyObject *
2267win32_popen2(PyObject *self, PyObject *args)
2268{
2269 PyObject *f;
2270 int tm=0;
2271
2272 char *cmdstring;
2273 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002274 int bufsize = -1;
2275 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002276 return NULL;
2277
2278 if (*mode == 't')
2279 tm = _O_TEXT;
2280 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002281 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002282 return NULL;
2283 } else
2284 tm = _O_BINARY;
2285
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002286 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002287 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002288 return NULL;
2289 }
2290
2291 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002292
2293 return f;
2294}
2295
2296/*
2297 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002298 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002299 * The result of this function is 3 pipes - the process's stdin,
2300 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002301 */
2302
2303static PyObject *
2304win32_popen3(PyObject *self, PyObject *args)
2305{
2306 PyObject *f;
2307 int tm = 0;
2308
2309 char *cmdstring;
2310 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002311 int bufsize = -1;
2312 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002313 return NULL;
2314
2315 if (*mode == 't')
2316 tm = _O_TEXT;
2317 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002318 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002319 return NULL;
2320 } else
2321 tm = _O_BINARY;
2322
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002323 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002324 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002325 return NULL;
2326 }
2327
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002328 f = _PyPopen(cmdstring, tm, POPEN_3);
2329
2330 return f;
2331}
2332
2333/*
2334 * Variation on win32pipe.popen
2335 *
2336 * The result of this function is 2 pipes - the processes stdin,
2337 * and stdout+stderr combined as a single pipe.
2338 */
2339
2340static PyObject *
2341win32_popen4(PyObject *self, PyObject *args)
2342{
2343 PyObject *f;
2344 int tm = 0;
2345
2346 char *cmdstring;
2347 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002348 int bufsize = -1;
2349 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002350 return NULL;
2351
2352 if (*mode == 't')
2353 tm = _O_TEXT;
2354 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002355 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002356 return NULL;
2357 } else
2358 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002359
2360 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002361 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002362 return NULL;
2363 }
2364
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002365 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002366
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002367 return f;
2368}
2369
Mark Hammond08501372001-01-31 07:30:29 +00002370static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002371_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002372 HANDLE hStdin,
2373 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002374 HANDLE hStderr,
2375 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002376{
2377 PROCESS_INFORMATION piProcInfo;
2378 STARTUPINFO siStartInfo;
2379 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002380 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002381 int i;
2382 int x;
2383
2384 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2385 s1 = (char *)_alloca(i);
2386 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2387 return x;
2388 if (GetVersion() < 0x80000000) {
2389 /*
2390 * NT/2000
2391 */
2392 x = i + strlen(s3) + strlen(cmdstring) + 1;
2393 s2 = (char *)_alloca(x);
2394 ZeroMemory(s2, x);
2395 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2396 }
2397 else {
2398 /*
2399 * Oh gag, we're on Win9x. Use the workaround listed in
2400 * KB: Q150956
2401 */
Mark Hammond08501372001-01-31 07:30:29 +00002402 char modulepath[_MAX_PATH];
2403 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002404 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2405 for (i = x = 0; modulepath[i]; i++)
2406 if (modulepath[i] == '\\')
2407 x = i+1;
2408 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002409 /* Create the full-name to w9xpopen, so we can test it exists */
2410 strncat(modulepath,
2411 szConsoleSpawn,
2412 (sizeof(modulepath)/sizeof(modulepath[0]))
2413 -strlen(modulepath));
2414 if (stat(modulepath, &statinfo) != 0) {
2415 /* Eeek - file-not-found - possibly an embedding
2416 situation - see if we can locate it in sys.prefix
2417 */
2418 strncpy(modulepath,
2419 Py_GetExecPrefix(),
2420 sizeof(modulepath)/sizeof(modulepath[0]));
2421 if (modulepath[strlen(modulepath)-1] != '\\')
2422 strcat(modulepath, "\\");
2423 strncat(modulepath,
2424 szConsoleSpawn,
2425 (sizeof(modulepath)/sizeof(modulepath[0]))
2426 -strlen(modulepath));
2427 /* No where else to look - raise an easily identifiable
2428 error, rather than leaving Windows to report
2429 "file not found" - as the user is probably blissfully
2430 unaware this shim EXE is used, and it will confuse them.
2431 (well, it confused me for a while ;-)
2432 */
2433 if (stat(modulepath, &statinfo) != 0) {
2434 PyErr_Format(PyExc_RuntimeError,
2435 "Can not locate '%s' which is needed "
2436 "for popen to work on this platform.",
2437 szConsoleSpawn);
2438 return FALSE;
2439 }
2440 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002441 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2442 strlen(modulepath) +
2443 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002444
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002445 s2 = (char *)_alloca(x);
2446 ZeroMemory(s2, x);
2447 sprintf(
2448 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002449 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002450 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002451 s1,
2452 s3,
2453 cmdstring);
2454 }
2455 }
2456
2457 /* Could be an else here to try cmd.exe / command.com in the path
2458 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002459 else {
2460 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2461 return FALSE;
2462 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002463
2464 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2465 siStartInfo.cb = sizeof(STARTUPINFO);
2466 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2467 siStartInfo.hStdInput = hStdin;
2468 siStartInfo.hStdOutput = hStdout;
2469 siStartInfo.hStdError = hStderr;
2470 siStartInfo.wShowWindow = SW_HIDE;
2471
2472 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002473 s2,
2474 NULL,
2475 NULL,
2476 TRUE,
2477 CREATE_NEW_CONSOLE,
2478 NULL,
2479 NULL,
2480 &siStartInfo,
2481 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002482 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002483 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002484
Mark Hammondb37a3732000-08-14 04:47:33 +00002485 /* Return process handle */
2486 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002487 return TRUE;
2488 }
Mark Hammond08501372001-01-31 07:30:29 +00002489 win32_error("CreateProcess", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002490 return FALSE;
2491}
2492
2493/* The following code is based off of KB: Q190351 */
2494
2495static PyObject *
2496_PyPopen(char *cmdstring, int mode, int n)
2497{
2498 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2499 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002500 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002501
2502 SECURITY_ATTRIBUTES saAttr;
2503 BOOL fSuccess;
2504 int fd1, fd2, fd3;
2505 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002506 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002507 PyObject *f;
2508
2509 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2510 saAttr.bInheritHandle = TRUE;
2511 saAttr.lpSecurityDescriptor = NULL;
2512
2513 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2514 return win32_error("CreatePipe", NULL);
2515
2516 /* Create new output read handle and the input write handle. Set
2517 * the inheritance properties to FALSE. Otherwise, the child inherits
2518 * the these handles; resulting in non-closeable handles to the pipes
2519 * being created. */
2520 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002521 GetCurrentProcess(), &hChildStdinWrDup, 0,
2522 FALSE,
2523 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002524 if (!fSuccess)
2525 return win32_error("DuplicateHandle", NULL);
2526
2527 /* Close the inheritable version of ChildStdin
2528 that we're using. */
2529 CloseHandle(hChildStdinWr);
2530
2531 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2532 return win32_error("CreatePipe", NULL);
2533
2534 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002535 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2536 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002537 if (!fSuccess)
2538 return win32_error("DuplicateHandle", NULL);
2539
2540 /* Close the inheritable version of ChildStdout
2541 that we're using. */
2542 CloseHandle(hChildStdoutRd);
2543
2544 if (n != POPEN_4) {
2545 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2546 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002547 fSuccess = DuplicateHandle(GetCurrentProcess(),
2548 hChildStderrRd,
2549 GetCurrentProcess(),
2550 &hChildStderrRdDup, 0,
2551 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002552 if (!fSuccess)
2553 return win32_error("DuplicateHandle", NULL);
2554 /* Close the inheritable version of ChildStdErr that we're using. */
2555 CloseHandle(hChildStderrRd);
2556 }
2557
2558 switch (n) {
2559 case POPEN_1:
2560 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2561 case _O_WRONLY | _O_TEXT:
2562 /* Case for writing to child Stdin in text mode. */
2563 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2564 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002565 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002566 PyFile_SetBufSize(f, 0);
2567 /* We don't care about these pipes anymore, so close them. */
2568 CloseHandle(hChildStdoutRdDup);
2569 CloseHandle(hChildStderrRdDup);
2570 break;
2571
2572 case _O_RDONLY | _O_TEXT:
2573 /* Case for reading from child Stdout in text mode. */
2574 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2575 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002576 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002577 PyFile_SetBufSize(f, 0);
2578 /* We don't care about these pipes anymore, so close them. */
2579 CloseHandle(hChildStdinWrDup);
2580 CloseHandle(hChildStderrRdDup);
2581 break;
2582
2583 case _O_RDONLY | _O_BINARY:
2584 /* Case for readinig from child Stdout in binary mode. */
2585 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2586 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002587 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002588 PyFile_SetBufSize(f, 0);
2589 /* We don't care about these pipes anymore, so close them. */
2590 CloseHandle(hChildStdinWrDup);
2591 CloseHandle(hChildStderrRdDup);
2592 break;
2593
2594 case _O_WRONLY | _O_BINARY:
2595 /* Case for writing to child Stdin in binary mode. */
2596 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2597 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002598 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002599 PyFile_SetBufSize(f, 0);
2600 /* We don't care about these pipes anymore, so close them. */
2601 CloseHandle(hChildStdoutRdDup);
2602 CloseHandle(hChildStderrRdDup);
2603 break;
2604 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002605 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002606 break;
2607
2608 case POPEN_2:
2609 case POPEN_4:
2610 {
2611 char *m1, *m2;
2612 PyObject *p1, *p2;
2613
2614 if (mode && _O_TEXT) {
2615 m1 = "r";
2616 m2 = "w";
2617 } else {
2618 m1 = "rb";
2619 m2 = "wb";
2620 }
2621
2622 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2623 f1 = _fdopen(fd1, m2);
2624 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2625 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002626 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002627 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002628 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002629 PyFile_SetBufSize(p2, 0);
2630
2631 if (n != 4)
2632 CloseHandle(hChildStderrRdDup);
2633
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002634 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002635 Py_XDECREF(p1);
2636 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002637 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002638 break;
2639 }
2640
2641 case POPEN_3:
2642 {
2643 char *m1, *m2;
2644 PyObject *p1, *p2, *p3;
2645
2646 if (mode && _O_TEXT) {
2647 m1 = "r";
2648 m2 = "w";
2649 } else {
2650 m1 = "rb";
2651 m2 = "wb";
2652 }
2653
2654 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2655 f1 = _fdopen(fd1, m2);
2656 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2657 f2 = _fdopen(fd2, m1);
2658 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2659 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002660 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002661 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2662 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002663 PyFile_SetBufSize(p1, 0);
2664 PyFile_SetBufSize(p2, 0);
2665 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002666 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002667 Py_XDECREF(p1);
2668 Py_XDECREF(p2);
2669 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002670 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002671 break;
2672 }
2673 }
2674
2675 if (n == POPEN_4) {
2676 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002677 hChildStdinRd,
2678 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002679 hChildStdoutWr,
2680 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002681 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002682 }
2683 else {
2684 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002685 hChildStdinRd,
2686 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002687 hChildStderrWr,
2688 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002689 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002690 }
2691
Mark Hammondb37a3732000-08-14 04:47:33 +00002692 /*
2693 * Insert the files we've created into the process dictionary
2694 * all referencing the list with the process handle and the
2695 * initial number of files (see description below in _PyPclose).
2696 * Since if _PyPclose later tried to wait on a process when all
2697 * handles weren't closed, it could create a deadlock with the
2698 * child, we spend some energy here to try to ensure that we
2699 * either insert all file handles into the dictionary or none
2700 * at all. It's a little clumsy with the various popen modes
2701 * and variable number of files involved.
2702 */
2703 if (!_PyPopenProcs) {
2704 _PyPopenProcs = PyDict_New();
2705 }
2706
2707 if (_PyPopenProcs) {
2708 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2709 int ins_rc[3];
2710
2711 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2712 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2713
2714 procObj = PyList_New(2);
2715 hProcessObj = PyLong_FromVoidPtr(hProcess);
2716 intObj = PyInt_FromLong(file_count);
2717
2718 if (procObj && hProcessObj && intObj) {
2719 PyList_SetItem(procObj,0,hProcessObj);
2720 PyList_SetItem(procObj,1,intObj);
2721
2722 fileObj[0] = PyLong_FromVoidPtr(f1);
2723 if (fileObj[0]) {
2724 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2725 fileObj[0],
2726 procObj);
2727 }
2728 if (file_count >= 2) {
2729 fileObj[1] = PyLong_FromVoidPtr(f2);
2730 if (fileObj[1]) {
2731 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2732 fileObj[1],
2733 procObj);
2734 }
2735 }
2736 if (file_count >= 3) {
2737 fileObj[2] = PyLong_FromVoidPtr(f3);
2738 if (fileObj[2]) {
2739 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2740 fileObj[2],
2741 procObj);
2742 }
2743 }
2744
2745 if (ins_rc[0] < 0 || !fileObj[0] ||
2746 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2747 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2748 /* Something failed - remove any dictionary
2749 * entries that did make it.
2750 */
2751 if (!ins_rc[0] && fileObj[0]) {
2752 PyDict_DelItem(_PyPopenProcs,
2753 fileObj[0]);
2754 }
2755 if (!ins_rc[1] && fileObj[1]) {
2756 PyDict_DelItem(_PyPopenProcs,
2757 fileObj[1]);
2758 }
2759 if (!ins_rc[2] && fileObj[2]) {
2760 PyDict_DelItem(_PyPopenProcs,
2761 fileObj[2]);
2762 }
2763 }
2764 }
2765
2766 /*
2767 * Clean up our localized references for the dictionary keys
2768 * and value since PyDict_SetItem will Py_INCREF any copies
2769 * that got placed in the dictionary.
2770 */
2771 Py_XDECREF(procObj);
2772 Py_XDECREF(fileObj[0]);
2773 Py_XDECREF(fileObj[1]);
2774 Py_XDECREF(fileObj[2]);
2775 }
2776
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002777 /* Child is launched. Close the parents copy of those pipe
2778 * handles that only the child should have open. You need to
2779 * make sure that no handles to the write end of the output pipe
2780 * are maintained in this process or else the pipe will not close
2781 * when the child process exits and the ReadFile will hang. */
2782
2783 if (!CloseHandle(hChildStdinRd))
2784 return win32_error("CloseHandle", NULL);
2785
2786 if (!CloseHandle(hChildStdoutWr))
2787 return win32_error("CloseHandle", NULL);
2788
2789 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2790 return win32_error("CloseHandle", NULL);
2791
2792 return f;
2793}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002794
2795/*
2796 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2797 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002798 *
2799 * This function uses the _PyPopenProcs dictionary in order to map the
2800 * input file pointer to information about the process that was
2801 * originally created by the popen* call that created the file pointer.
2802 * The dictionary uses the file pointer as a key (with one entry
2803 * inserted for each file returned by the original popen* call) and a
2804 * single list object as the value for all files from a single call.
2805 * The list object contains the Win32 process handle at [0], and a file
2806 * count at [1], which is initialized to the total number of file
2807 * handles using that list.
2808 *
2809 * This function closes whichever handle it is passed, and decrements
2810 * the file count in the dictionary for the process handle pointed to
2811 * by this file. On the last close (when the file count reaches zero),
2812 * this function will wait for the child process and then return its
2813 * exit code as the result of the close() operation. This permits the
2814 * files to be closed in any order - it is always the close() of the
2815 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002816 */
Tim Peters736aa322000-09-01 06:51:24 +00002817
2818 /* RED_FLAG 31-Aug-2000 Tim
2819 * This is always called (today!) between a pair of
2820 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2821 * macros. So the thread running this has no valid thread state, as
2822 * far as Python is concerned. However, this calls some Python API
2823 * functions that cannot be called safely without a valid thread
2824 * state, in particular PyDict_GetItem.
2825 * As a temporary hack (although it may last for years ...), we
2826 * *rely* on not having a valid thread state in this function, in
2827 * order to create our own "from scratch".
2828 * This will deadlock if _PyPclose is ever called by a thread
2829 * holding the global lock.
2830 */
2831
Fredrik Lundh56055a42000-07-23 19:47:12 +00002832static int _PyPclose(FILE *file)
2833{
Fredrik Lundh20318932000-07-26 17:29:12 +00002834 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002835 DWORD exit_code;
2836 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002837 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2838 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002839#ifdef WITH_THREAD
2840 PyInterpreterState* pInterpreterState;
2841 PyThreadState* pThreadState;
2842#endif
2843
Fredrik Lundh20318932000-07-26 17:29:12 +00002844 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002845 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002846 */
2847 result = fclose(file);
2848
Tim Peters736aa322000-09-01 06:51:24 +00002849#ifdef WITH_THREAD
2850 /* Bootstrap a valid thread state into existence. */
2851 pInterpreterState = PyInterpreterState_New();
2852 if (!pInterpreterState) {
2853 /* Well, we're hosed now! We don't have a thread
2854 * state, so can't call a nice error routine, or raise
2855 * an exception. Just die.
2856 */
2857 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002858 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002859 return -1; /* unreachable */
2860 }
2861 pThreadState = PyThreadState_New(pInterpreterState);
2862 if (!pThreadState) {
2863 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002864 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002865 return -1; /* unreachable */
2866 }
2867 /* Grab the global lock. Note that this will deadlock if the
2868 * current thread already has the lock! (see RED_FLAG comments
2869 * before this function)
2870 */
2871 PyEval_RestoreThread(pThreadState);
2872#endif
2873
Fredrik Lundh56055a42000-07-23 19:47:12 +00002874 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002875 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2876 (procObj = PyDict_GetItem(_PyPopenProcs,
2877 fileObj)) != NULL &&
2878 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2879 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2880
2881 hProcess = PyLong_AsVoidPtr(hProcessObj);
2882 file_count = PyInt_AsLong(intObj);
2883
2884 if (file_count > 1) {
2885 /* Still other files referencing process */
2886 file_count--;
2887 PyList_SetItem(procObj,1,
2888 PyInt_FromLong(file_count));
2889 } else {
2890 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002891 if (result != EOF &&
2892 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2893 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002894 /* Possible truncation here in 16-bit environments, but
2895 * real exit codes are just the lower byte in any event.
2896 */
2897 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002898 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002899 /* Indicate failure - this will cause the file object
2900 * to raise an I/O error and translate the last Win32
2901 * error code from errno. We do have a problem with
2902 * last errors that overlap the normal errno table,
2903 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002904 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002905 if (result != EOF) {
2906 /* If the error wasn't from the fclose(), then
2907 * set errno for the file object error handling.
2908 */
2909 errno = GetLastError();
2910 }
2911 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002912 }
2913
2914 /* Free up the native handle at this point */
2915 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002916 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002917
Mark Hammondb37a3732000-08-14 04:47:33 +00002918 /* Remove this file pointer from dictionary */
2919 PyDict_DelItem(_PyPopenProcs, fileObj);
2920
2921 if (PyDict_Size(_PyPopenProcs) == 0) {
2922 Py_DECREF(_PyPopenProcs);
2923 _PyPopenProcs = NULL;
2924 }
2925
2926 } /* if object retrieval ok */
2927
2928 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002929 } /* if _PyPopenProcs */
2930
Tim Peters736aa322000-09-01 06:51:24 +00002931#ifdef WITH_THREAD
2932 /* Tear down the thread & interpreter states.
2933 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002934 * call the thread clear & delete functions, and indeed insist on
2935 * doing that themselves. The lock must be held during the clear, but
2936 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002937 */
2938 PyInterpreterState_Clear(pInterpreterState);
2939 PyEval_ReleaseThread(pThreadState);
2940 PyInterpreterState_Delete(pInterpreterState);
2941#endif
2942
Fredrik Lundh56055a42000-07-23 19:47:12 +00002943 return result;
2944}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002945
2946#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002948posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002949{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002950 char *name;
2951 char *mode = "r";
2952 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002953 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002954 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002955 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002956 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002957 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002958 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002959 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002960 if (fp == NULL)
2961 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002962 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002963 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002964 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002965 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002966}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002967#endif
2968
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002969#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002970
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002971
Guido van Rossumb6775db1994-08-01 11:34:53 +00002972#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002973static char posix_setuid__doc__[] =
2974"setuid(uid) -> None\n\
2975Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002977posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002978{
2979 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002980 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002981 return NULL;
2982 if (setuid(uid) < 0)
2983 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002984 Py_INCREF(Py_None);
2985 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002986}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002987#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002988
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002989
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002990#ifdef HAVE_SETEUID
2991static char posix_seteuid__doc__[] =
2992"seteuid(uid) -> None\n\
2993Set the current process's effective user id.";
2994static PyObject *
2995posix_seteuid (PyObject *self, PyObject *args)
2996{
2997 int euid;
2998 if (!PyArg_ParseTuple(args, "i", &euid)) {
2999 return NULL;
3000 } else if (seteuid(euid) < 0) {
3001 return posix_error();
3002 } else {
3003 Py_INCREF(Py_None);
3004 return Py_None;
3005 }
3006}
3007#endif /* HAVE_SETEUID */
3008
3009#ifdef HAVE_SETEGID
3010static char posix_setegid__doc__[] =
3011"setegid(gid) -> None\n\
3012Set the current process's effective group id.";
3013static PyObject *
3014posix_setegid (PyObject *self, PyObject *args)
3015{
3016 int egid;
3017 if (!PyArg_ParseTuple(args, "i", &egid)) {
3018 return NULL;
3019 } else if (setegid(egid) < 0) {
3020 return posix_error();
3021 } else {
3022 Py_INCREF(Py_None);
3023 return Py_None;
3024 }
3025}
3026#endif /* HAVE_SETEGID */
3027
3028#ifdef HAVE_SETREUID
3029static char posix_setreuid__doc__[] =
3030"seteuid(ruid, euid) -> None\n\
3031Set the current process's real and effective user ids.";
3032static PyObject *
3033posix_setreuid (PyObject *self, PyObject *args)
3034{
3035 int ruid, euid;
3036 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3037 return NULL;
3038 } else if (setreuid(ruid, euid) < 0) {
3039 return posix_error();
3040 } else {
3041 Py_INCREF(Py_None);
3042 return Py_None;
3043 }
3044}
3045#endif /* HAVE_SETREUID */
3046
3047#ifdef HAVE_SETREGID
3048static char posix_setregid__doc__[] =
3049"setegid(rgid, egid) -> None\n\
3050Set the current process's real and effective group ids.";
3051static PyObject *
3052posix_setregid (PyObject *self, PyObject *args)
3053{
3054 int rgid, egid;
3055 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3056 return NULL;
3057 } else if (setregid(rgid, egid) < 0) {
3058 return posix_error();
3059 } else {
3060 Py_INCREF(Py_None);
3061 return Py_None;
3062 }
3063}
3064#endif /* HAVE_SETREGID */
3065
Guido van Rossumb6775db1994-08-01 11:34:53 +00003066#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003067static char posix_setgid__doc__[] =
3068"setgid(gid) -> None\n\
3069Set the current process's group id.";
3070
Barry Warsaw53699e91996-12-10 23:23:01 +00003071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003072posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003073{
3074 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003075 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003076 return NULL;
3077 if (setgid(gid) < 0)
3078 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003079 Py_INCREF(Py_None);
3080 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003081}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003082#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003084
Guido van Rossumb6775db1994-08-01 11:34:53 +00003085#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003086static char posix_waitpid__doc__[] =
3087"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003088Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003089
Barry Warsaw53699e91996-12-10 23:23:01 +00003090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003091posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003092{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003093 int pid, options;
3094#ifdef UNION_WAIT
3095 union wait status;
3096#define status_i (status.w_status)
3097#else
3098 int status;
3099#define status_i status
3100#endif
3101 status_i = 0;
3102
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003103 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003104 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003105 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003106#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003107 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003108#else
3109 pid = waitpid(pid, &status, options);
3110#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003111 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003112 if (pid == -1)
3113 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003114 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003115 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003116}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003117#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003119
Guido van Rossumad0ee831995-03-01 10:34:45 +00003120#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003121static char posix_wait__doc__[] =
3122"wait() -> (pid, status)\n\
3123Wait for completion of a child process.";
3124
Barry Warsaw53699e91996-12-10 23:23:01 +00003125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003126posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003127{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003128 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003129#ifdef UNION_WAIT
3130 union wait status;
3131#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003132#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003133 int status;
3134#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003135#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003136 if (!PyArg_ParseTuple(args, ":wait"))
3137 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003138 status_i = 0;
3139 Py_BEGIN_ALLOW_THREADS
3140 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003141 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003142 if (pid == -1)
3143 return posix_error();
3144 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003145 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003146#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003147}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003148#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003149
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003150
3151static char posix_lstat__doc__[] =
3152"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3153Like stat(path), but do not follow symbolic links.";
3154
Barry Warsaw53699e91996-12-10 23:23:01 +00003155static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003156posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003157{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003158#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003159 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003160#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003161 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003162#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003163}
3164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003165
Guido van Rossumb6775db1994-08-01 11:34:53 +00003166#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003167static char posix_readlink__doc__[] =
3168"readlink(path) -> path\n\
3169Return a string representing the path to which the symbolic link points.";
3170
Barry Warsaw53699e91996-12-10 23:23:01 +00003171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003172posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003173{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003174 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003175 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003176 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003177 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003178 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003179 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003180 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003181 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003182 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003183 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003184 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003185}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003186#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003188
Guido van Rossumb6775db1994-08-01 11:34:53 +00003189#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003190static char posix_symlink__doc__[] =
3191"symlink(src, dst) -> None\n\
3192Create a symbolic link.";
3193
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003195posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003196{
Mark Hammondef8b6542001-05-13 08:04:26 +00003197 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003198}
3199#endif /* HAVE_SYMLINK */
3200
3201
3202#ifdef HAVE_TIMES
3203#ifndef HZ
3204#define HZ 60 /* Universal constant :-) */
3205#endif /* HZ */
3206
Guido van Rossumd48f2521997-12-05 22:19:34 +00003207#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3208static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003209system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003210{
3211 ULONG value = 0;
3212
3213 Py_BEGIN_ALLOW_THREADS
3214 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3215 Py_END_ALLOW_THREADS
3216
3217 return value;
3218}
3219
3220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003221posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003222{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003223 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003224 return NULL;
3225
3226 /* Currently Only Uptime is Provided -- Others Later */
3227 return Py_BuildValue("ddddd",
3228 (double)0 /* t.tms_utime / HZ */,
3229 (double)0 /* t.tms_stime / HZ */,
3230 (double)0 /* t.tms_cutime / HZ */,
3231 (double)0 /* t.tms_cstime / HZ */,
3232 (double)system_uptime() / 1000);
3233}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003234#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003236posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003237{
3238 struct tms t;
3239 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003240 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003241 return NULL;
3242 errno = 0;
3243 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003244 if (c == (clock_t) -1)
3245 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003246 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003247 (double)t.tms_utime / HZ,
3248 (double)t.tms_stime / HZ,
3249 (double)t.tms_cutime / HZ,
3250 (double)t.tms_cstime / HZ,
3251 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003252}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003253#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003254#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003255
3256
Guido van Rossum87755a21996-09-07 00:59:43 +00003257#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003258#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003260posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003261{
3262 FILETIME create, exit, kernel, user;
3263 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003264 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003265 return NULL;
3266 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003267 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3268 /* The fields of a FILETIME structure are the hi and lo part
3269 of a 64-bit value expressed in 100 nanosecond units.
3270 1e7 is one second in such units; 1e-7 the inverse.
3271 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3272 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003273 return Py_BuildValue(
3274 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003275 (double)(kernel.dwHighDateTime*429.4967296 +
3276 kernel.dwLowDateTime*1e-7),
3277 (double)(user.dwHighDateTime*429.4967296 +
3278 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003279 (double)0,
3280 (double)0,
3281 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003282}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003283#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003284
3285#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003286static char posix_times__doc__[] =
3287"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3288Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003289#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003291
Guido van Rossumb6775db1994-08-01 11:34:53 +00003292#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003293static char posix_setsid__doc__[] =
3294"setsid() -> None\n\
3295Call the system call setsid().";
3296
Barry Warsaw53699e91996-12-10 23:23:01 +00003297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003298posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003299{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003300 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003301 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003302 if (setsid() < 0)
3303 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003304 Py_INCREF(Py_None);
3305 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003306}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003307#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003308
Guido van Rossumb6775db1994-08-01 11:34:53 +00003309#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003310static char posix_setpgid__doc__[] =
3311"setpgid(pid, pgrp) -> None\n\
3312Call the system call setpgid().";
3313
Barry Warsaw53699e91996-12-10 23:23:01 +00003314static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003315posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003316{
3317 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003318 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003319 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003320 if (setpgid(pid, pgrp) < 0)
3321 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003322 Py_INCREF(Py_None);
3323 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003324}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003325#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003327
Guido van Rossumb6775db1994-08-01 11:34:53 +00003328#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003329static char posix_tcgetpgrp__doc__[] =
3330"tcgetpgrp(fd) -> pgid\n\
3331Return the process group associated with the terminal given by a fd.";
3332
Barry Warsaw53699e91996-12-10 23:23:01 +00003333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003334posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003335{
3336 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003337 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003338 return NULL;
3339 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003340 if (pgid < 0)
3341 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003342 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003343}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003344#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003346
Guido van Rossumb6775db1994-08-01 11:34:53 +00003347#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003348static char posix_tcsetpgrp__doc__[] =
3349"tcsetpgrp(fd, pgid) -> None\n\
3350Set the process group associated with the terminal given by a fd.";
3351
Barry Warsaw53699e91996-12-10 23:23:01 +00003352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003353posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003354{
3355 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003356 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003357 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003358 if (tcsetpgrp(fd, pgid) < 0)
3359 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003360 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003361 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003362}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003363#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003364
Guido van Rossum687dd131993-05-17 08:34:16 +00003365/* Functions acting on file descriptors */
3366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003367static char posix_open__doc__[] =
3368"open(filename, flag [, mode=0777]) -> fd\n\
3369Open a file (for low level IO).";
3370
Barry Warsaw53699e91996-12-10 23:23:01 +00003371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003372posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003373{
Mark Hammondef8b6542001-05-13 08:04:26 +00003374 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003375 int flag;
3376 int mode = 0777;
3377 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003378 if (!PyArg_ParseTuple(args, "eti|i",
3379 Py_FileSystemDefaultEncoding, &file,
3380 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003381 return NULL;
3382
Barry Warsaw53699e91996-12-10 23:23:01 +00003383 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003384 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003385 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003386 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003387 return posix_error_with_allocated_filename(file);
3388 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003389 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003390}
3391
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003392
3393static char posix_close__doc__[] =
3394"close(fd) -> None\n\
3395Close a file descriptor (for low level IO).";
3396
Barry Warsaw53699e91996-12-10 23:23:01 +00003397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003398posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003399{
3400 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003401 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003402 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003403 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003404 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003405 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003406 if (res < 0)
3407 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003408 Py_INCREF(Py_None);
3409 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003410}
3411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003412
3413static char posix_dup__doc__[] =
3414"dup(fd) -> fd2\n\
3415Return a duplicate of a file descriptor.";
3416
Barry Warsaw53699e91996-12-10 23:23:01 +00003417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003418posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003419{
3420 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003421 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003422 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003423 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003424 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003425 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003426 if (fd < 0)
3427 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003428 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003429}
3430
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003431
3432static char posix_dup2__doc__[] =
3433"dup2(fd, fd2) -> None\n\
3434Duplicate file descriptor.";
3435
Barry Warsaw53699e91996-12-10 23:23:01 +00003436static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003437posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003438{
3439 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003440 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003441 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003442 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003443 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003444 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003445 if (res < 0)
3446 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003447 Py_INCREF(Py_None);
3448 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003449}
3450
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003451
3452static char posix_lseek__doc__[] =
3453"lseek(fd, pos, how) -> newpos\n\
3454Set the current position of a file descriptor.";
3455
Barry Warsaw53699e91996-12-10 23:23:01 +00003456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003457posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003458{
3459 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003460#ifdef MS_WIN64
3461 LONG_LONG pos, res;
3462#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003463 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003464#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003465 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003466 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003467 return NULL;
3468#ifdef SEEK_SET
3469 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3470 switch (how) {
3471 case 0: how = SEEK_SET; break;
3472 case 1: how = SEEK_CUR; break;
3473 case 2: how = SEEK_END; break;
3474 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003475#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003476
3477#if !defined(HAVE_LARGEFILE_SUPPORT)
3478 pos = PyInt_AsLong(posobj);
3479#else
3480 pos = PyLong_Check(posobj) ?
3481 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3482#endif
3483 if (PyErr_Occurred())
3484 return NULL;
3485
Barry Warsaw53699e91996-12-10 23:23:01 +00003486 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003487#ifdef MS_WIN64
3488 res = _lseeki64(fd, pos, how);
3489#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003490 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003491#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003492 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003493 if (res < 0)
3494 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003495
3496#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003497 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003498#else
3499 return PyLong_FromLongLong(res);
3500#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003501}
3502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003503
3504static char posix_read__doc__[] =
3505"read(fd, buffersize) -> string\n\
3506Read a file descriptor.";
3507
Barry Warsaw53699e91996-12-10 23:23:01 +00003508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003509posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003510{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003511 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003512 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003513 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003514 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003515 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003516 if (buffer == NULL)
3517 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003518 Py_BEGIN_ALLOW_THREADS
3519 n = read(fd, PyString_AsString(buffer), size);
3520 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003521 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003522 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003523 return posix_error();
3524 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003525 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003526 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003527 return buffer;
3528}
3529
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003530
3531static char posix_write__doc__[] =
3532"write(fd, string) -> byteswritten\n\
3533Write a string to a file descriptor.";
3534
Barry Warsaw53699e91996-12-10 23:23:01 +00003535static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003536posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003537{
3538 int fd, size;
3539 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003540 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003541 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003542 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003543 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003544 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003545 if (size < 0)
3546 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003547 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003548}
3549
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003550
3551static char posix_fstat__doc__[]=
3552"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3553Like stat(), but for an open file descriptor.";
3554
Barry Warsaw53699e91996-12-10 23:23:01 +00003555static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003556posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003557{
3558 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003559 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003560 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003561 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003562 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003563 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003564 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003565 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003566 if (res != 0)
3567 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003568
3569 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003570}
3571
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003572
3573static char posix_fdopen__doc__[] =
3574"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3575Return an open file object connected to a file descriptor.";
3576
Barry Warsaw53699e91996-12-10 23:23:01 +00003577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003578posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003579{
Guido van Rossum687dd131993-05-17 08:34:16 +00003580 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003581 char *mode = "r";
3582 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003583 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003584 PyObject *f;
3585 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003586 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003587
Barry Warsaw53699e91996-12-10 23:23:01 +00003588 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003589 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003590 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003591 if (fp == NULL)
3592 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003593 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003594 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003595 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003596 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003597}
3598
Skip Montanaro1517d842000-07-19 14:34:14 +00003599static char posix_isatty__doc__[] =
3600"isatty(fd) -> Boolean\n\
3601Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003602connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003603
3604static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003605posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003606{
3607 int fd;
3608 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3609 return NULL;
3610 return Py_BuildValue("i", isatty(fd));
3611}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003612
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003613#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003614static char posix_pipe__doc__[] =
3615"pipe() -> (read_end, write_end)\n\
3616Create a pipe.";
3617
Barry Warsaw53699e91996-12-10 23:23:01 +00003618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003619posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003620{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003621#if defined(PYOS_OS2)
3622 HFILE read, write;
3623 APIRET rc;
3624
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003625 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003626 return NULL;
3627
3628 Py_BEGIN_ALLOW_THREADS
3629 rc = DosCreatePipe( &read, &write, 4096);
3630 Py_END_ALLOW_THREADS
3631 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003632 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003633
3634 return Py_BuildValue("(ii)", read, write);
3635#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003636#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003637 int fds[2];
3638 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003639 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003640 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003641 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003642 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003643 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003644 if (res != 0)
3645 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003646 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003647#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003648 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003649 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003650 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003651 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003652 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003653 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003654 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003655 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003656 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003657 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003658 read_fd = _open_osfhandle((intptr_t)read, 0);
3659 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003660 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003661#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003662#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003663}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003664#endif /* HAVE_PIPE */
3665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003666
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003667#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003668static char posix_mkfifo__doc__[] =
3669"mkfifo(file, [, mode=0666]) -> None\n\
3670Create a FIFO (a POSIX named pipe).";
3671
Barry Warsaw53699e91996-12-10 23:23:01 +00003672static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003673posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003674{
3675 char *file;
3676 int mode = 0666;
3677 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003678 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003679 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003680 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003681 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003682 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003683 if (res < 0)
3684 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003685 Py_INCREF(Py_None);
3686 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003687}
3688#endif
3689
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003690
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003691#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003692static char posix_ftruncate__doc__[] =
3693"ftruncate(fd, length) -> None\n\
3694Truncate a file to a specified length.";
3695
Barry Warsaw53699e91996-12-10 23:23:01 +00003696static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003697posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003698{
3699 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003700 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003701 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003702 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003703
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003704 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003705 return NULL;
3706
3707#if !defined(HAVE_LARGEFILE_SUPPORT)
3708 length = PyInt_AsLong(lenobj);
3709#else
3710 length = PyLong_Check(lenobj) ?
3711 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3712#endif
3713 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003714 return NULL;
3715
Barry Warsaw53699e91996-12-10 23:23:01 +00003716 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003717 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003718 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003719 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003720 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003721 return NULL;
3722 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003723 Py_INCREF(Py_None);
3724 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003725}
3726#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003727
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003728#ifdef NeXT
3729#define HAVE_PUTENV
3730/* Steve Spicklemire got this putenv from NeXTAnswers */
3731static int
3732putenv(char *newval)
3733{
3734 extern char **environ;
3735
3736 static int firstTime = 1;
3737 char **ep;
3738 char *cp;
3739 int esiz;
3740 char *np;
3741
3742 if (!(np = strchr(newval, '=')))
3743 return 1;
3744 *np = '\0';
3745
3746 /* look it up */
3747 for (ep=environ ; *ep ; ep++)
3748 {
3749 /* this should always be true... */
3750 if (cp = strchr(*ep, '='))
3751 {
3752 *cp = '\0';
3753 if (!strcmp(*ep, newval))
3754 {
3755 /* got it! */
3756 *cp = '=';
3757 break;
3758 }
3759 *cp = '=';
3760 }
3761 else
3762 {
3763 *np = '=';
3764 return 1;
3765 }
3766 }
3767
3768 *np = '=';
3769 if (*ep)
3770 {
3771 /* the string was already there:
3772 just replace it with the new one */
3773 *ep = newval;
3774 return 0;
3775 }
3776
3777 /* expand environ by one */
3778 for (esiz=2, ep=environ ; *ep ; ep++)
3779 esiz++;
3780 if (firstTime)
3781 {
3782 char **epp;
3783 char **newenv;
3784 if (!(newenv = malloc(esiz * sizeof(char *))))
3785 return 1;
3786
3787 for (ep=environ, epp=newenv ; *ep ;)
3788 *epp++ = *ep++;
3789 *epp++ = newval;
3790 *epp = (char *) 0;
3791 environ = newenv;
3792 }
3793 else
3794 {
3795 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3796 return 1;
3797 environ[esiz - 2] = newval;
3798 environ[esiz - 1] = (char *) 0;
3799 firstTime = 0;
3800 }
3801
3802 return 0;
3803}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003804#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003805
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003806
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003807#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003808static char posix_putenv__doc__[] =
3809"putenv(key, value) -> None\n\
3810Change or add an environment variable.";
3811
Fred Drake762e2061999-08-26 17:23:54 +00003812/* Save putenv() parameters as values here, so we can collect them when they
3813 * get re-set with another call for the same key. */
3814static PyObject *posix_putenv_garbage;
3815
Barry Warsaw53699e91996-12-10 23:23:01 +00003816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003817posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003818{
3819 char *s1, *s2;
3820 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003821 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003822
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003823 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003824 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003825
3826#if defined(PYOS_OS2)
3827 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3828 APIRET rc;
3829
3830 if (strlen(s2) == 0) /* If New Value is an Empty String */
3831 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3832
3833 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3834 if (rc != NO_ERROR)
3835 return os2_error(rc);
3836
3837 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3838 APIRET rc;
3839
3840 if (strlen(s2) == 0) /* If New Value is an Empty String */
3841 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3842
3843 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3844 if (rc != NO_ERROR)
3845 return os2_error(rc);
3846 } else {
3847#endif
3848
Fred Drake762e2061999-08-26 17:23:54 +00003849 /* XXX This can leak memory -- not easy to fix :-( */
3850 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3851 if (newstr == NULL)
3852 return PyErr_NoMemory();
3853 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003854 (void) sprintf(new, "%s=%s", s1, s2);
3855 if (putenv(new)) {
3856 posix_error();
3857 return NULL;
3858 }
Fred Drake762e2061999-08-26 17:23:54 +00003859 /* Install the first arg and newstr in posix_putenv_garbage;
3860 * this will cause previous value to be collected. This has to
3861 * happen after the real putenv() call because the old value
3862 * was still accessible until then. */
3863 if (PyDict_SetItem(posix_putenv_garbage,
3864 PyTuple_GET_ITEM(args, 0), newstr)) {
3865 /* really not much we can do; just leak */
3866 PyErr_Clear();
3867 }
3868 else {
3869 Py_DECREF(newstr);
3870 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003871
3872#if defined(PYOS_OS2)
3873 }
3874#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003875 Py_INCREF(Py_None);
3876 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003877}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003878#endif /* putenv */
3879
3880#ifdef HAVE_STRERROR
3881static char posix_strerror__doc__[] =
3882"strerror(code) -> string\n\
3883Translate an error code to a message string.";
3884
Guido van Rossumf68d8e52001-04-14 17:55:09 +00003885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003886posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003887{
3888 int code;
3889 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003890 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003891 return NULL;
3892 message = strerror(code);
3893 if (message == NULL) {
3894 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003895 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003896 return NULL;
3897 }
3898 return PyString_FromString(message);
3899}
3900#endif /* strerror */
3901
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003902
Guido van Rossumc9641791998-08-04 15:26:23 +00003903#ifdef HAVE_SYS_WAIT_H
3904
3905#ifdef WIFSTOPPED
3906static char posix_WIFSTOPPED__doc__[] =
3907"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003908Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003909
3910static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003911posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003912{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003913#ifdef UNION_WAIT
3914 union wait status;
3915#define status_i (status.w_status)
3916#else
3917 int status;
3918#define status_i status
3919#endif
3920 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003921
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003922 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003923 {
3924 return NULL;
3925 }
3926
3927 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003928#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003929}
3930#endif /* WIFSTOPPED */
3931
3932#ifdef WIFSIGNALED
3933static char posix_WIFSIGNALED__doc__[] =
3934"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003935Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003936
3937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003938posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003939{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003940#ifdef UNION_WAIT
3941 union wait status;
3942#define status_i (status.w_status)
3943#else
3944 int status;
3945#define status_i status
3946#endif
3947 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003948
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003949 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003950 {
3951 return NULL;
3952 }
3953
3954 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003955#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003956}
3957#endif /* WIFSIGNALED */
3958
3959#ifdef WIFEXITED
3960static char posix_WIFEXITED__doc__[] =
3961"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003962Return true if the process returning 'status' exited using the exit()\n\
3963system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003964
3965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003966posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003967{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003968#ifdef UNION_WAIT
3969 union wait status;
3970#define status_i (status.w_status)
3971#else
3972 int status;
3973#define status_i status
3974#endif
3975 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003976
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003977 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003978 {
3979 return NULL;
3980 }
3981
3982 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003983#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003984}
3985#endif /* WIFEXITED */
3986
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003987#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003988static char posix_WEXITSTATUS__doc__[] =
3989"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003990Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003991
3992static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003993posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003994{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003995#ifdef UNION_WAIT
3996 union wait status;
3997#define status_i (status.w_status)
3998#else
3999 int status;
4000#define status_i status
4001#endif
4002 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004003
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004004 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004005 {
4006 return NULL;
4007 }
4008
4009 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004010#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004011}
4012#endif /* WEXITSTATUS */
4013
4014#ifdef WTERMSIG
4015static char posix_WTERMSIG__doc__[] =
4016"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004017Return the signal that terminated the process that provided the 'status'\n\
4018value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004019
4020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004021posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004022{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004023#ifdef UNION_WAIT
4024 union wait status;
4025#define status_i (status.w_status)
4026#else
4027 int status;
4028#define status_i status
4029#endif
4030 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004031
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004032 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004033 {
4034 return NULL;
4035 }
4036
4037 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004038#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004039}
4040#endif /* WTERMSIG */
4041
4042#ifdef WSTOPSIG
4043static char posix_WSTOPSIG__doc__[] =
4044"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004045Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004046
4047static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004048posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004049{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004050#ifdef UNION_WAIT
4051 union wait status;
4052#define status_i (status.w_status)
4053#else
4054 int status;
4055#define status_i status
4056#endif
4057 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004058
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004059 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004060 {
4061 return NULL;
4062 }
4063
4064 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004065#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004066}
4067#endif /* WSTOPSIG */
4068
4069#endif /* HAVE_SYS_WAIT_H */
4070
4071
Guido van Rossum94f6f721999-01-06 18:42:14 +00004072#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004073#ifdef _SCO_DS
4074/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4075 needed definitions in sys/statvfs.h */
4076#define _SVID3
4077#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004078#include <sys/statvfs.h>
4079
4080static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004081"fstatvfs(fd) -> \n\
4082 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004083Perform an fstatvfs system call on the given fd.";
4084
4085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004086posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004087{
4088 int fd, res;
4089 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004090 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004091 return NULL;
4092 Py_BEGIN_ALLOW_THREADS
4093 res = fstatvfs(fd, &st);
4094 Py_END_ALLOW_THREADS
4095 if (res != 0)
4096 return posix_error();
4097#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004098 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004099 (long) st.f_bsize,
4100 (long) st.f_frsize,
4101 (long) st.f_blocks,
4102 (long) st.f_bfree,
4103 (long) st.f_bavail,
4104 (long) st.f_files,
4105 (long) st.f_ffree,
4106 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004107 (long) st.f_flag,
4108 (long) st.f_namemax);
4109#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004110 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004111 (long) st.f_bsize,
4112 (long) st.f_frsize,
4113 (LONG_LONG) st.f_blocks,
4114 (LONG_LONG) st.f_bfree,
4115 (LONG_LONG) st.f_bavail,
4116 (LONG_LONG) st.f_files,
4117 (LONG_LONG) st.f_ffree,
4118 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004119 (long) st.f_flag,
4120 (long) st.f_namemax);
4121#endif
4122}
4123#endif /* HAVE_FSTATVFS */
4124
4125
4126#if defined(HAVE_STATVFS)
4127#include <sys/statvfs.h>
4128
4129static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004130"statvfs(path) -> \n\
4131 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004132Perform a statvfs system call on the given path.";
4133
4134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004135posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004136{
4137 char *path;
4138 int res;
4139 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004140 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004141 return NULL;
4142 Py_BEGIN_ALLOW_THREADS
4143 res = statvfs(path, &st);
4144 Py_END_ALLOW_THREADS
4145 if (res != 0)
4146 return posix_error_with_filename(path);
4147#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004148 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004149 (long) st.f_bsize,
4150 (long) st.f_frsize,
4151 (long) st.f_blocks,
4152 (long) st.f_bfree,
4153 (long) st.f_bavail,
4154 (long) st.f_files,
4155 (long) st.f_ffree,
4156 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004157 (long) st.f_flag,
4158 (long) st.f_namemax);
4159#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004160 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004161 (long) st.f_bsize,
4162 (long) st.f_frsize,
4163 (LONG_LONG) st.f_blocks,
4164 (LONG_LONG) st.f_bfree,
4165 (LONG_LONG) st.f_bavail,
4166 (LONG_LONG) st.f_files,
4167 (LONG_LONG) st.f_ffree,
4168 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004169 (long) st.f_flag,
4170 (long) st.f_namemax);
4171#endif
4172}
4173#endif /* HAVE_STATVFS */
4174
4175
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004176#ifdef HAVE_TEMPNAM
4177static char posix_tempnam__doc__[] = "\
4178tempnam([dir[, prefix]]) -> string\n\
4179Return a unique name for a temporary file.\n\
4180The directory and a short may be specified as strings; they may be omitted\n\
4181or None if not needed.";
4182
4183static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004184posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004185{
4186 PyObject *result = NULL;
4187 char *dir = NULL;
4188 char *pfx = NULL;
4189 char *name;
4190
4191 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4192 return NULL;
4193 name = tempnam(dir, pfx);
4194 if (name == NULL)
4195 return PyErr_NoMemory();
4196 result = PyString_FromString(name);
4197 free(name);
4198 return result;
4199}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004200#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004201
4202
4203#ifdef HAVE_TMPFILE
4204static char posix_tmpfile__doc__[] = "\
4205tmpfile() -> file object\n\
4206Create a temporary file with no directory entries.";
4207
4208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004209posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004210{
4211 FILE *fp;
4212
4213 if (!PyArg_ParseTuple(args, ":tmpfile"))
4214 return NULL;
4215 fp = tmpfile();
4216 if (fp == NULL)
4217 return posix_error();
4218 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4219}
4220#endif
4221
4222
4223#ifdef HAVE_TMPNAM
4224static char posix_tmpnam__doc__[] = "\
4225tmpnam() -> string\n\
4226Return a unique name for a temporary file.";
4227
4228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004229posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004230{
4231 char buffer[L_tmpnam];
4232 char *name;
4233
4234 if (!PyArg_ParseTuple(args, ":tmpnam"))
4235 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004236#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004237 name = tmpnam_r(buffer);
4238#else
4239 name = tmpnam(buffer);
4240#endif
4241 if (name == NULL) {
4242 PyErr_SetObject(PyExc_OSError,
4243 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004244#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004245 "unexpected NULL from tmpnam_r"
4246#else
4247 "unexpected NULL from tmpnam"
4248#endif
4249 ));
4250 return NULL;
4251 }
4252 return PyString_FromString(buffer);
4253}
4254#endif
4255
4256
Fred Drakec9680921999-12-13 16:37:25 +00004257/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4258 * It maps strings representing configuration variable names to
4259 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004260 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004261 * rarely-used constants. There are three separate tables that use
4262 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004263 *
4264 * This code is always included, even if none of the interfaces that
4265 * need it are included. The #if hackery needed to avoid it would be
4266 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004267 */
4268struct constdef {
4269 char *name;
4270 long value;
4271};
4272
Fred Drake12c6e2d1999-12-14 21:25:03 +00004273static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004274conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4275 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004276{
4277 if (PyInt_Check(arg)) {
4278 *valuep = PyInt_AS_LONG(arg);
4279 return 1;
4280 }
4281 if (PyString_Check(arg)) {
4282 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004283 size_t lo = 0;
4284 size_t mid;
4285 size_t hi = tablesize;
4286 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004287 char *confname = PyString_AS_STRING(arg);
4288 while (lo < hi) {
4289 mid = (lo + hi) / 2;
4290 cmp = strcmp(confname, table[mid].name);
4291 if (cmp < 0)
4292 hi = mid;
4293 else if (cmp > 0)
4294 lo = mid + 1;
4295 else {
4296 *valuep = table[mid].value;
4297 return 1;
4298 }
4299 }
4300 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4301 }
4302 else
4303 PyErr_SetString(PyExc_TypeError,
4304 "configuration names must be strings or integers");
4305 return 0;
4306}
4307
4308
4309#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4310static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004311#ifdef _PC_ABI_AIO_XFER_MAX
4312 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4313#endif
4314#ifdef _PC_ABI_ASYNC_IO
4315 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4316#endif
Fred Drakec9680921999-12-13 16:37:25 +00004317#ifdef _PC_ASYNC_IO
4318 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4319#endif
4320#ifdef _PC_CHOWN_RESTRICTED
4321 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4322#endif
4323#ifdef _PC_FILESIZEBITS
4324 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4325#endif
4326#ifdef _PC_LAST
4327 {"PC_LAST", _PC_LAST},
4328#endif
4329#ifdef _PC_LINK_MAX
4330 {"PC_LINK_MAX", _PC_LINK_MAX},
4331#endif
4332#ifdef _PC_MAX_CANON
4333 {"PC_MAX_CANON", _PC_MAX_CANON},
4334#endif
4335#ifdef _PC_MAX_INPUT
4336 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4337#endif
4338#ifdef _PC_NAME_MAX
4339 {"PC_NAME_MAX", _PC_NAME_MAX},
4340#endif
4341#ifdef _PC_NO_TRUNC
4342 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4343#endif
4344#ifdef _PC_PATH_MAX
4345 {"PC_PATH_MAX", _PC_PATH_MAX},
4346#endif
4347#ifdef _PC_PIPE_BUF
4348 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4349#endif
4350#ifdef _PC_PRIO_IO
4351 {"PC_PRIO_IO", _PC_PRIO_IO},
4352#endif
4353#ifdef _PC_SOCK_MAXBUF
4354 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4355#endif
4356#ifdef _PC_SYNC_IO
4357 {"PC_SYNC_IO", _PC_SYNC_IO},
4358#endif
4359#ifdef _PC_VDISABLE
4360 {"PC_VDISABLE", _PC_VDISABLE},
4361#endif
4362};
4363
Fred Drakec9680921999-12-13 16:37:25 +00004364static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004365conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004366{
4367 return conv_confname(arg, valuep, posix_constants_pathconf,
4368 sizeof(posix_constants_pathconf)
4369 / sizeof(struct constdef));
4370}
4371#endif
4372
4373#ifdef HAVE_FPATHCONF
4374static char posix_fpathconf__doc__[] = "\
4375fpathconf(fd, name) -> integer\n\
4376Return the configuration limit name for the file descriptor fd.\n\
4377If there is no limit, return -1.";
4378
4379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004380posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004381{
4382 PyObject *result = NULL;
4383 int name, fd;
4384
Fred Drake12c6e2d1999-12-14 21:25:03 +00004385 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4386 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004387 long limit;
4388
4389 errno = 0;
4390 limit = fpathconf(fd, name);
4391 if (limit == -1 && errno != 0)
4392 posix_error();
4393 else
4394 result = PyInt_FromLong(limit);
4395 }
4396 return result;
4397}
4398#endif
4399
4400
4401#ifdef HAVE_PATHCONF
4402static char posix_pathconf__doc__[] = "\
4403pathconf(path, name) -> integer\n\
4404Return the configuration limit name for the file or directory path.\n\
4405If there is no limit, return -1.";
4406
4407static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004408posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004409{
4410 PyObject *result = NULL;
4411 int name;
4412 char *path;
4413
4414 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4415 conv_path_confname, &name)) {
4416 long limit;
4417
4418 errno = 0;
4419 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004420 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004421 if (errno == EINVAL)
4422 /* could be a path or name problem */
4423 posix_error();
4424 else
4425 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004426 }
Fred Drakec9680921999-12-13 16:37:25 +00004427 else
4428 result = PyInt_FromLong(limit);
4429 }
4430 return result;
4431}
4432#endif
4433
4434#ifdef HAVE_CONFSTR
4435static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004436#ifdef _CS_ARCHITECTURE
4437 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4438#endif
4439#ifdef _CS_HOSTNAME
4440 {"CS_HOSTNAME", _CS_HOSTNAME},
4441#endif
4442#ifdef _CS_HW_PROVIDER
4443 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4444#endif
4445#ifdef _CS_HW_SERIAL
4446 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4447#endif
4448#ifdef _CS_INITTAB_NAME
4449 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4450#endif
Fred Drakec9680921999-12-13 16:37:25 +00004451#ifdef _CS_LFS64_CFLAGS
4452 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4453#endif
4454#ifdef _CS_LFS64_LDFLAGS
4455 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4456#endif
4457#ifdef _CS_LFS64_LIBS
4458 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4459#endif
4460#ifdef _CS_LFS64_LINTFLAGS
4461 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4462#endif
4463#ifdef _CS_LFS_CFLAGS
4464 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4465#endif
4466#ifdef _CS_LFS_LDFLAGS
4467 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4468#endif
4469#ifdef _CS_LFS_LIBS
4470 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4471#endif
4472#ifdef _CS_LFS_LINTFLAGS
4473 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4474#endif
Fred Draked86ed291999-12-15 15:34:33 +00004475#ifdef _CS_MACHINE
4476 {"CS_MACHINE", _CS_MACHINE},
4477#endif
Fred Drakec9680921999-12-13 16:37:25 +00004478#ifdef _CS_PATH
4479 {"CS_PATH", _CS_PATH},
4480#endif
Fred Draked86ed291999-12-15 15:34:33 +00004481#ifdef _CS_RELEASE
4482 {"CS_RELEASE", _CS_RELEASE},
4483#endif
4484#ifdef _CS_SRPC_DOMAIN
4485 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4486#endif
4487#ifdef _CS_SYSNAME
4488 {"CS_SYSNAME", _CS_SYSNAME},
4489#endif
4490#ifdef _CS_VERSION
4491 {"CS_VERSION", _CS_VERSION},
4492#endif
Fred Drakec9680921999-12-13 16:37:25 +00004493#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4494 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4495#endif
4496#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4497 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4498#endif
4499#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4500 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4501#endif
4502#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4503 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4504#endif
4505#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4506 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4507#endif
4508#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4509 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4510#endif
4511#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4512 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4513#endif
4514#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4515 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4516#endif
4517#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4518 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4519#endif
4520#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4521 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4522#endif
4523#ifdef _CS_XBS5_LP64_OFF64_LIBS
4524 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4525#endif
4526#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4527 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4528#endif
4529#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4530 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4531#endif
4532#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4533 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4534#endif
4535#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4536 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4537#endif
4538#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4539 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4540#endif
Fred Draked86ed291999-12-15 15:34:33 +00004541#ifdef _MIPS_CS_AVAIL_PROCESSORS
4542 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4543#endif
4544#ifdef _MIPS_CS_BASE
4545 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4546#endif
4547#ifdef _MIPS_CS_HOSTID
4548 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4549#endif
4550#ifdef _MIPS_CS_HW_NAME
4551 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4552#endif
4553#ifdef _MIPS_CS_NUM_PROCESSORS
4554 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4555#endif
4556#ifdef _MIPS_CS_OSREL_MAJ
4557 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4558#endif
4559#ifdef _MIPS_CS_OSREL_MIN
4560 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4561#endif
4562#ifdef _MIPS_CS_OSREL_PATCH
4563 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4564#endif
4565#ifdef _MIPS_CS_OS_NAME
4566 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4567#endif
4568#ifdef _MIPS_CS_OS_PROVIDER
4569 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4570#endif
4571#ifdef _MIPS_CS_PROCESSORS
4572 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4573#endif
4574#ifdef _MIPS_CS_SERIAL
4575 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4576#endif
4577#ifdef _MIPS_CS_VENDOR
4578 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4579#endif
Fred Drakec9680921999-12-13 16:37:25 +00004580};
4581
4582static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004583conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004584{
4585 return conv_confname(arg, valuep, posix_constants_confstr,
4586 sizeof(posix_constants_confstr)
4587 / sizeof(struct constdef));
4588}
4589
4590static char posix_confstr__doc__[] = "\
4591confstr(name) -> string\n\
4592Return a string-valued system configuration variable.";
4593
4594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004595posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004596{
4597 PyObject *result = NULL;
4598 int name;
4599 char buffer[64];
4600
4601 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4602 int len = confstr(name, buffer, sizeof(buffer));
4603
Fred Drakec9680921999-12-13 16:37:25 +00004604 errno = 0;
4605 if (len == 0) {
4606 if (errno != 0)
4607 posix_error();
4608 else
4609 result = PyString_FromString("");
4610 }
4611 else {
4612 if (len >= sizeof(buffer)) {
4613 result = PyString_FromStringAndSize(NULL, len);
4614 if (result != NULL)
4615 confstr(name, PyString_AS_STRING(result), len+1);
4616 }
4617 else
4618 result = PyString_FromString(buffer);
4619 }
4620 }
4621 return result;
4622}
4623#endif
4624
4625
4626#ifdef HAVE_SYSCONF
4627static struct constdef posix_constants_sysconf[] = {
4628#ifdef _SC_2_CHAR_TERM
4629 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4630#endif
4631#ifdef _SC_2_C_BIND
4632 {"SC_2_C_BIND", _SC_2_C_BIND},
4633#endif
4634#ifdef _SC_2_C_DEV
4635 {"SC_2_C_DEV", _SC_2_C_DEV},
4636#endif
4637#ifdef _SC_2_C_VERSION
4638 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4639#endif
4640#ifdef _SC_2_FORT_DEV
4641 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4642#endif
4643#ifdef _SC_2_FORT_RUN
4644 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4645#endif
4646#ifdef _SC_2_LOCALEDEF
4647 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4648#endif
4649#ifdef _SC_2_SW_DEV
4650 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4651#endif
4652#ifdef _SC_2_UPE
4653 {"SC_2_UPE", _SC_2_UPE},
4654#endif
4655#ifdef _SC_2_VERSION
4656 {"SC_2_VERSION", _SC_2_VERSION},
4657#endif
Fred Draked86ed291999-12-15 15:34:33 +00004658#ifdef _SC_ABI_ASYNCHRONOUS_IO
4659 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4660#endif
4661#ifdef _SC_ACL
4662 {"SC_ACL", _SC_ACL},
4663#endif
Fred Drakec9680921999-12-13 16:37:25 +00004664#ifdef _SC_AIO_LISTIO_MAX
4665 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4666#endif
Fred Drakec9680921999-12-13 16:37:25 +00004667#ifdef _SC_AIO_MAX
4668 {"SC_AIO_MAX", _SC_AIO_MAX},
4669#endif
4670#ifdef _SC_AIO_PRIO_DELTA_MAX
4671 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4672#endif
4673#ifdef _SC_ARG_MAX
4674 {"SC_ARG_MAX", _SC_ARG_MAX},
4675#endif
4676#ifdef _SC_ASYNCHRONOUS_IO
4677 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4678#endif
4679#ifdef _SC_ATEXIT_MAX
4680 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4681#endif
Fred Draked86ed291999-12-15 15:34:33 +00004682#ifdef _SC_AUDIT
4683 {"SC_AUDIT", _SC_AUDIT},
4684#endif
Fred Drakec9680921999-12-13 16:37:25 +00004685#ifdef _SC_AVPHYS_PAGES
4686 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4687#endif
4688#ifdef _SC_BC_BASE_MAX
4689 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4690#endif
4691#ifdef _SC_BC_DIM_MAX
4692 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4693#endif
4694#ifdef _SC_BC_SCALE_MAX
4695 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4696#endif
4697#ifdef _SC_BC_STRING_MAX
4698 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4699#endif
Fred Draked86ed291999-12-15 15:34:33 +00004700#ifdef _SC_CAP
4701 {"SC_CAP", _SC_CAP},
4702#endif
Fred Drakec9680921999-12-13 16:37:25 +00004703#ifdef _SC_CHARCLASS_NAME_MAX
4704 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4705#endif
4706#ifdef _SC_CHAR_BIT
4707 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4708#endif
4709#ifdef _SC_CHAR_MAX
4710 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4711#endif
4712#ifdef _SC_CHAR_MIN
4713 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4714#endif
4715#ifdef _SC_CHILD_MAX
4716 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4717#endif
4718#ifdef _SC_CLK_TCK
4719 {"SC_CLK_TCK", _SC_CLK_TCK},
4720#endif
4721#ifdef _SC_COHER_BLKSZ
4722 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4723#endif
4724#ifdef _SC_COLL_WEIGHTS_MAX
4725 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4726#endif
4727#ifdef _SC_DCACHE_ASSOC
4728 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4729#endif
4730#ifdef _SC_DCACHE_BLKSZ
4731 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4732#endif
4733#ifdef _SC_DCACHE_LINESZ
4734 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4735#endif
4736#ifdef _SC_DCACHE_SZ
4737 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4738#endif
4739#ifdef _SC_DCACHE_TBLKSZ
4740 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4741#endif
4742#ifdef _SC_DELAYTIMER_MAX
4743 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4744#endif
4745#ifdef _SC_EQUIV_CLASS_MAX
4746 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4747#endif
4748#ifdef _SC_EXPR_NEST_MAX
4749 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4750#endif
4751#ifdef _SC_FSYNC
4752 {"SC_FSYNC", _SC_FSYNC},
4753#endif
4754#ifdef _SC_GETGR_R_SIZE_MAX
4755 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4756#endif
4757#ifdef _SC_GETPW_R_SIZE_MAX
4758 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4759#endif
4760#ifdef _SC_ICACHE_ASSOC
4761 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4762#endif
4763#ifdef _SC_ICACHE_BLKSZ
4764 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4765#endif
4766#ifdef _SC_ICACHE_LINESZ
4767 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4768#endif
4769#ifdef _SC_ICACHE_SZ
4770 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4771#endif
Fred Draked86ed291999-12-15 15:34:33 +00004772#ifdef _SC_INF
4773 {"SC_INF", _SC_INF},
4774#endif
Fred Drakec9680921999-12-13 16:37:25 +00004775#ifdef _SC_INT_MAX
4776 {"SC_INT_MAX", _SC_INT_MAX},
4777#endif
4778#ifdef _SC_INT_MIN
4779 {"SC_INT_MIN", _SC_INT_MIN},
4780#endif
4781#ifdef _SC_IOV_MAX
4782 {"SC_IOV_MAX", _SC_IOV_MAX},
4783#endif
Fred Draked86ed291999-12-15 15:34:33 +00004784#ifdef _SC_IP_SECOPTS
4785 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4786#endif
Fred Drakec9680921999-12-13 16:37:25 +00004787#ifdef _SC_JOB_CONTROL
4788 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4789#endif
Fred Draked86ed291999-12-15 15:34:33 +00004790#ifdef _SC_KERN_POINTERS
4791 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4792#endif
4793#ifdef _SC_KERN_SIM
4794 {"SC_KERN_SIM", _SC_KERN_SIM},
4795#endif
Fred Drakec9680921999-12-13 16:37:25 +00004796#ifdef _SC_LINE_MAX
4797 {"SC_LINE_MAX", _SC_LINE_MAX},
4798#endif
4799#ifdef _SC_LOGIN_NAME_MAX
4800 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4801#endif
4802#ifdef _SC_LOGNAME_MAX
4803 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4804#endif
4805#ifdef _SC_LONG_BIT
4806 {"SC_LONG_BIT", _SC_LONG_BIT},
4807#endif
Fred Draked86ed291999-12-15 15:34:33 +00004808#ifdef _SC_MAC
4809 {"SC_MAC", _SC_MAC},
4810#endif
Fred Drakec9680921999-12-13 16:37:25 +00004811#ifdef _SC_MAPPED_FILES
4812 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4813#endif
4814#ifdef _SC_MAXPID
4815 {"SC_MAXPID", _SC_MAXPID},
4816#endif
4817#ifdef _SC_MB_LEN_MAX
4818 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4819#endif
4820#ifdef _SC_MEMLOCK
4821 {"SC_MEMLOCK", _SC_MEMLOCK},
4822#endif
4823#ifdef _SC_MEMLOCK_RANGE
4824 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4825#endif
4826#ifdef _SC_MEMORY_PROTECTION
4827 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4828#endif
4829#ifdef _SC_MESSAGE_PASSING
4830 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4831#endif
Fred Draked86ed291999-12-15 15:34:33 +00004832#ifdef _SC_MMAP_FIXED_ALIGNMENT
4833 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4834#endif
Fred Drakec9680921999-12-13 16:37:25 +00004835#ifdef _SC_MQ_OPEN_MAX
4836 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4837#endif
4838#ifdef _SC_MQ_PRIO_MAX
4839 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4840#endif
Fred Draked86ed291999-12-15 15:34:33 +00004841#ifdef _SC_NACLS_MAX
4842 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4843#endif
Fred Drakec9680921999-12-13 16:37:25 +00004844#ifdef _SC_NGROUPS_MAX
4845 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4846#endif
4847#ifdef _SC_NL_ARGMAX
4848 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4849#endif
4850#ifdef _SC_NL_LANGMAX
4851 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4852#endif
4853#ifdef _SC_NL_MSGMAX
4854 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4855#endif
4856#ifdef _SC_NL_NMAX
4857 {"SC_NL_NMAX", _SC_NL_NMAX},
4858#endif
4859#ifdef _SC_NL_SETMAX
4860 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4861#endif
4862#ifdef _SC_NL_TEXTMAX
4863 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4864#endif
4865#ifdef _SC_NPROCESSORS_CONF
4866 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4867#endif
4868#ifdef _SC_NPROCESSORS_ONLN
4869 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4870#endif
Fred Draked86ed291999-12-15 15:34:33 +00004871#ifdef _SC_NPROC_CONF
4872 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4873#endif
4874#ifdef _SC_NPROC_ONLN
4875 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4876#endif
Fred Drakec9680921999-12-13 16:37:25 +00004877#ifdef _SC_NZERO
4878 {"SC_NZERO", _SC_NZERO},
4879#endif
4880#ifdef _SC_OPEN_MAX
4881 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4882#endif
4883#ifdef _SC_PAGESIZE
4884 {"SC_PAGESIZE", _SC_PAGESIZE},
4885#endif
4886#ifdef _SC_PAGE_SIZE
4887 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4888#endif
4889#ifdef _SC_PASS_MAX
4890 {"SC_PASS_MAX", _SC_PASS_MAX},
4891#endif
4892#ifdef _SC_PHYS_PAGES
4893 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4894#endif
4895#ifdef _SC_PII
4896 {"SC_PII", _SC_PII},
4897#endif
4898#ifdef _SC_PII_INTERNET
4899 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4900#endif
4901#ifdef _SC_PII_INTERNET_DGRAM
4902 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4903#endif
4904#ifdef _SC_PII_INTERNET_STREAM
4905 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4906#endif
4907#ifdef _SC_PII_OSI
4908 {"SC_PII_OSI", _SC_PII_OSI},
4909#endif
4910#ifdef _SC_PII_OSI_CLTS
4911 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4912#endif
4913#ifdef _SC_PII_OSI_COTS
4914 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4915#endif
4916#ifdef _SC_PII_OSI_M
4917 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4918#endif
4919#ifdef _SC_PII_SOCKET
4920 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4921#endif
4922#ifdef _SC_PII_XTI
4923 {"SC_PII_XTI", _SC_PII_XTI},
4924#endif
4925#ifdef _SC_POLL
4926 {"SC_POLL", _SC_POLL},
4927#endif
4928#ifdef _SC_PRIORITIZED_IO
4929 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4930#endif
4931#ifdef _SC_PRIORITY_SCHEDULING
4932 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4933#endif
4934#ifdef _SC_REALTIME_SIGNALS
4935 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4936#endif
4937#ifdef _SC_RE_DUP_MAX
4938 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4939#endif
4940#ifdef _SC_RTSIG_MAX
4941 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4942#endif
4943#ifdef _SC_SAVED_IDS
4944 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4945#endif
4946#ifdef _SC_SCHAR_MAX
4947 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4948#endif
4949#ifdef _SC_SCHAR_MIN
4950 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4951#endif
4952#ifdef _SC_SELECT
4953 {"SC_SELECT", _SC_SELECT},
4954#endif
4955#ifdef _SC_SEMAPHORES
4956 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4957#endif
4958#ifdef _SC_SEM_NSEMS_MAX
4959 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4960#endif
4961#ifdef _SC_SEM_VALUE_MAX
4962 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4963#endif
4964#ifdef _SC_SHARED_MEMORY_OBJECTS
4965 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4966#endif
4967#ifdef _SC_SHRT_MAX
4968 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4969#endif
4970#ifdef _SC_SHRT_MIN
4971 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4972#endif
4973#ifdef _SC_SIGQUEUE_MAX
4974 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4975#endif
4976#ifdef _SC_SIGRT_MAX
4977 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4978#endif
4979#ifdef _SC_SIGRT_MIN
4980 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4981#endif
Fred Draked86ed291999-12-15 15:34:33 +00004982#ifdef _SC_SOFTPOWER
4983 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4984#endif
Fred Drakec9680921999-12-13 16:37:25 +00004985#ifdef _SC_SPLIT_CACHE
4986 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4987#endif
4988#ifdef _SC_SSIZE_MAX
4989 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4990#endif
4991#ifdef _SC_STACK_PROT
4992 {"SC_STACK_PROT", _SC_STACK_PROT},
4993#endif
4994#ifdef _SC_STREAM_MAX
4995 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4996#endif
4997#ifdef _SC_SYNCHRONIZED_IO
4998 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4999#endif
5000#ifdef _SC_THREADS
5001 {"SC_THREADS", _SC_THREADS},
5002#endif
5003#ifdef _SC_THREAD_ATTR_STACKADDR
5004 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5005#endif
5006#ifdef _SC_THREAD_ATTR_STACKSIZE
5007 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5008#endif
5009#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5010 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5011#endif
5012#ifdef _SC_THREAD_KEYS_MAX
5013 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5014#endif
5015#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5016 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5017#endif
5018#ifdef _SC_THREAD_PRIO_INHERIT
5019 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5020#endif
5021#ifdef _SC_THREAD_PRIO_PROTECT
5022 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5023#endif
5024#ifdef _SC_THREAD_PROCESS_SHARED
5025 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5026#endif
5027#ifdef _SC_THREAD_SAFE_FUNCTIONS
5028 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5029#endif
5030#ifdef _SC_THREAD_STACK_MIN
5031 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5032#endif
5033#ifdef _SC_THREAD_THREADS_MAX
5034 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5035#endif
5036#ifdef _SC_TIMERS
5037 {"SC_TIMERS", _SC_TIMERS},
5038#endif
5039#ifdef _SC_TIMER_MAX
5040 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5041#endif
5042#ifdef _SC_TTY_NAME_MAX
5043 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5044#endif
5045#ifdef _SC_TZNAME_MAX
5046 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5047#endif
5048#ifdef _SC_T_IOV_MAX
5049 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5050#endif
5051#ifdef _SC_UCHAR_MAX
5052 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5053#endif
5054#ifdef _SC_UINT_MAX
5055 {"SC_UINT_MAX", _SC_UINT_MAX},
5056#endif
5057#ifdef _SC_UIO_MAXIOV
5058 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5059#endif
5060#ifdef _SC_ULONG_MAX
5061 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5062#endif
5063#ifdef _SC_USHRT_MAX
5064 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5065#endif
5066#ifdef _SC_VERSION
5067 {"SC_VERSION", _SC_VERSION},
5068#endif
5069#ifdef _SC_WORD_BIT
5070 {"SC_WORD_BIT", _SC_WORD_BIT},
5071#endif
5072#ifdef _SC_XBS5_ILP32_OFF32
5073 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5074#endif
5075#ifdef _SC_XBS5_ILP32_OFFBIG
5076 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5077#endif
5078#ifdef _SC_XBS5_LP64_OFF64
5079 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5080#endif
5081#ifdef _SC_XBS5_LPBIG_OFFBIG
5082 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5083#endif
5084#ifdef _SC_XOPEN_CRYPT
5085 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5086#endif
5087#ifdef _SC_XOPEN_ENH_I18N
5088 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5089#endif
5090#ifdef _SC_XOPEN_LEGACY
5091 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5092#endif
5093#ifdef _SC_XOPEN_REALTIME
5094 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5095#endif
5096#ifdef _SC_XOPEN_REALTIME_THREADS
5097 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5098#endif
5099#ifdef _SC_XOPEN_SHM
5100 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5101#endif
5102#ifdef _SC_XOPEN_UNIX
5103 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5104#endif
5105#ifdef _SC_XOPEN_VERSION
5106 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5107#endif
5108#ifdef _SC_XOPEN_XCU_VERSION
5109 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5110#endif
5111#ifdef _SC_XOPEN_XPG2
5112 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5113#endif
5114#ifdef _SC_XOPEN_XPG3
5115 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5116#endif
5117#ifdef _SC_XOPEN_XPG4
5118 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5119#endif
5120};
5121
5122static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005123conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005124{
5125 return conv_confname(arg, valuep, posix_constants_sysconf,
5126 sizeof(posix_constants_sysconf)
5127 / sizeof(struct constdef));
5128}
5129
5130static char posix_sysconf__doc__[] = "\
5131sysconf(name) -> integer\n\
5132Return an integer-valued system configuration variable.";
5133
5134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005135posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005136{
5137 PyObject *result = NULL;
5138 int name;
5139
5140 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5141 int value;
5142
5143 errno = 0;
5144 value = sysconf(name);
5145 if (value == -1 && errno != 0)
5146 posix_error();
5147 else
5148 result = PyInt_FromLong(value);
5149 }
5150 return result;
5151}
5152#endif
5153
5154
Fred Drakebec628d1999-12-15 18:31:10 +00005155/* This code is used to ensure that the tables of configuration value names
5156 * are in sorted order as required by conv_confname(), and also to build the
5157 * the exported dictionaries that are used to publish information about the
5158 * names available on the host platform.
5159 *
5160 * Sorting the table at runtime ensures that the table is properly ordered
5161 * when used, even for platforms we're not able to test on. It also makes
5162 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005163 */
Fred Drakebec628d1999-12-15 18:31:10 +00005164
5165static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005166cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005167{
5168 const struct constdef *c1 =
5169 (const struct constdef *) v1;
5170 const struct constdef *c2 =
5171 (const struct constdef *) v2;
5172
5173 return strcmp(c1->name, c2->name);
5174}
5175
5176static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005177setup_confname_table(struct constdef *table, size_t tablesize,
5178 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005179{
Fred Drakebec628d1999-12-15 18:31:10 +00005180 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005181 size_t i;
5182 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005183
5184 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5185 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005186 if (d == NULL)
5187 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005188
Barry Warsaw3155db32000-04-13 15:20:40 +00005189 for (i=0; i < tablesize; ++i) {
5190 PyObject *o = PyInt_FromLong(table[i].value);
5191 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5192 Py_XDECREF(o);
5193 Py_DECREF(d);
5194 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005195 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005196 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005197 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005198 status = PyDict_SetItemString(moddict, tablename, d);
5199 Py_DECREF(d);
5200 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005201}
5202
Fred Drakebec628d1999-12-15 18:31:10 +00005203/* Return -1 on failure, 0 on success. */
5204static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005205setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005206{
5207#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005208 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005209 sizeof(posix_constants_pathconf)
5210 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005211 "pathconf_names", moddict))
5212 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005213#endif
5214#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005215 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005216 sizeof(posix_constants_confstr)
5217 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005218 "confstr_names", moddict))
5219 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005220#endif
5221#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005222 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005223 sizeof(posix_constants_sysconf)
5224 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005225 "sysconf_names", moddict))
5226 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005227#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005228 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005229}
Fred Draked86ed291999-12-15 15:34:33 +00005230
5231
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005232static char posix_abort__doc__[] = "\
5233abort() -> does not return!\n\
5234Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5235in the hardest way possible on the hosting operating system.";
5236
5237static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005238posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005239{
5240 if (!PyArg_ParseTuple(args, ":abort"))
5241 return NULL;
5242 abort();
5243 /*NOTREACHED*/
5244 Py_FatalError("abort() called from Python code didn't abort!");
5245 return NULL;
5246}
Fred Drakebec628d1999-12-15 18:31:10 +00005247
Tim Petersf58a7aa2000-09-22 10:05:54 +00005248#ifdef MS_WIN32
5249static char win32_startfile__doc__[] = "\
5250startfile(filepath) - Start a file with its associated application.\n\
5251\n\
5252This acts like double-clicking the file in Explorer, or giving the file\n\
5253name as an argument to the DOS \"start\" command: the file is opened\n\
5254with whatever application (if any) its extension is associated.\n\
5255\n\
5256startfile returns as soon as the associated application is launched.\n\
5257There is no option to wait for the application to close, and no way\n\
5258to retrieve the application's exit status.\n\
5259\n\
5260The filepath is relative to the current directory. If you want to use\n\
5261an absolute path, make sure the first character is not a slash (\"/\");\n\
5262the underlying Win32 ShellExecute function doesn't work if it is.";
5263
5264static PyObject *
5265win32_startfile(PyObject *self, PyObject *args)
5266{
5267 char *filepath;
5268 HINSTANCE rc;
5269 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5270 return NULL;
5271 Py_BEGIN_ALLOW_THREADS
5272 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5273 Py_END_ALLOW_THREADS
5274 if (rc <= (HINSTANCE)32)
5275 return win32_error("startfile", filepath);
5276 Py_INCREF(Py_None);
5277 return Py_None;
5278}
5279#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005280
5281static PyMethodDef posix_methods[] = {
5282 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5283#ifdef HAVE_TTYNAME
5284 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5285#endif
5286 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5287 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005288#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005289 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005290#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005291#ifdef HAVE_CTERMID
5292 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5293#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005294#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005295 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005296#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005297#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005298 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005299#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005300 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5301 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5302 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005303#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005304 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005305#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005306#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005307 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005308#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005309 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5310 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5311 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005312#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005313 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005314#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005315#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005316 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005317#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005318 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005319#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005320 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005321#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005322 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5323 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5324 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005325#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005326 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005327#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005328 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005329#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005330 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5331 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005332#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005333#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005334 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5335 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005336#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005337#ifdef HAVE_FORK1
5338 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5339#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005340#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005341 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005342#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005343#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005344 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005345#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005346#ifdef HAVE_FORKPTY
5347 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5348#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005349#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005350 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005351#endif /* HAVE_GETEGID */
5352#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005353 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005354#endif /* HAVE_GETEUID */
5355#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005356 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005357#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005358#ifdef HAVE_GETGROUPS
5359 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5360#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005361 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005362#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005363 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005364#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005365#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005366 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005367#endif /* HAVE_GETPPID */
5368#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005369 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005370#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005371#ifdef HAVE_GETLOGIN
5372 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5373#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005374#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005375 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005376#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005377#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005378 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005379#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005380#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005381 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005382#ifdef MS_WIN32
5383 {"popen2", win32_popen2, METH_VARARGS},
5384 {"popen3", win32_popen3, METH_VARARGS},
5385 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005386 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005387#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005388#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005389#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005390 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005391#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005392#ifdef HAVE_SETEUID
5393 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5394#endif /* HAVE_SETEUID */
5395#ifdef HAVE_SETEGID
5396 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5397#endif /* HAVE_SETEGID */
5398#ifdef HAVE_SETREUID
5399 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5400#endif /* HAVE_SETREUID */
5401#ifdef HAVE_SETREGID
5402 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5403#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005404#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005405 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005406#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005407#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005408 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005409#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005410#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005411 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005412#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005413#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005414 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005415#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005416#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005417 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005418#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005419#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005420 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005421#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005422#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005423 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005424#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005425#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005426 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005427#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005428 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5429 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5430 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5431 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5432 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5433 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5434 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5435 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5436 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005437 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005438#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005439 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005440#endif
5441#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005442 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005443#endif
5444#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005445 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005446#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005447#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005448 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005449#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005450#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005451 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005452#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005453#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005454 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005455#endif
5456#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005457 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005458#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005459#ifdef HAVE_SYS_WAIT_H
5460#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005461 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005462#endif /* WIFSTOPPED */
5463#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005464 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005465#endif /* WIFSIGNALED */
5466#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005467 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005468#endif /* WIFEXITED */
5469#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005470 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005471#endif /* WEXITSTATUS */
5472#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005473 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005474#endif /* WTERMSIG */
5475#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005476 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005477#endif /* WSTOPSIG */
5478#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005479#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005480 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005481#endif
5482#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005483 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005484#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005485#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005486 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5487#endif
5488#ifdef HAVE_TEMPNAM
5489 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5490#endif
5491#ifdef HAVE_TMPNAM
5492 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5493#endif
Fred Drakec9680921999-12-13 16:37:25 +00005494#ifdef HAVE_CONFSTR
5495 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5496#endif
5497#ifdef HAVE_SYSCONF
5498 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5499#endif
5500#ifdef HAVE_FPATHCONF
5501 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5502#endif
5503#ifdef HAVE_PATHCONF
5504 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5505#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005506 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005507#ifdef MS_WIN32
5508 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5509#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005510 {NULL, NULL} /* Sentinel */
5511};
5512
5513
Barry Warsaw4a342091996-12-19 23:50:02 +00005514static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005515ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005516{
5517 PyObject* v = PyInt_FromLong(value);
5518 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5519 return -1; /* triggers fatal error */
5520
5521 Py_DECREF(v);
5522 return 0;
5523}
5524
Guido van Rossumd48f2521997-12-05 22:19:34 +00005525#if defined(PYOS_OS2)
5526/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5527static int insertvalues(PyObject *d)
5528{
5529 APIRET rc;
5530 ULONG values[QSV_MAX+1];
5531 PyObject *v;
5532 char *ver, tmp[10];
5533
5534 Py_BEGIN_ALLOW_THREADS
5535 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5536 Py_END_ALLOW_THREADS
5537
5538 if (rc != NO_ERROR) {
5539 os2_error(rc);
5540 return -1;
5541 }
5542
5543 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5544 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5545 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5546 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5547 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5548 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5549 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5550
5551 switch (values[QSV_VERSION_MINOR]) {
5552 case 0: ver = "2.00"; break;
5553 case 10: ver = "2.10"; break;
5554 case 11: ver = "2.11"; break;
5555 case 30: ver = "3.00"; break;
5556 case 40: ver = "4.00"; break;
5557 case 50: ver = "5.00"; break;
5558 default:
5559 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5560 values[QSV_VERSION_MINOR]);
5561 ver = &tmp[0];
5562 }
5563
5564 /* Add Indicator of the Version of the Operating System */
5565 v = PyString_FromString(ver);
5566 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5567 return -1;
5568 Py_DECREF(v);
5569
5570 /* Add Indicator of Which Drive was Used to Boot the System */
5571 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5572 tmp[1] = ':';
5573 tmp[2] = '\0';
5574
5575 v = PyString_FromString(tmp);
5576 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5577 return -1;
5578 Py_DECREF(v);
5579
5580 return 0;
5581}
5582#endif
5583
Barry Warsaw4a342091996-12-19 23:50:02 +00005584static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005585all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005586{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005587#ifdef F_OK
5588 if (ins(d, "F_OK", (long)F_OK)) return -1;
5589#endif
5590#ifdef R_OK
5591 if (ins(d, "R_OK", (long)R_OK)) return -1;
5592#endif
5593#ifdef W_OK
5594 if (ins(d, "W_OK", (long)W_OK)) return -1;
5595#endif
5596#ifdef X_OK
5597 if (ins(d, "X_OK", (long)X_OK)) return -1;
5598#endif
Fred Drakec9680921999-12-13 16:37:25 +00005599#ifdef NGROUPS_MAX
5600 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5601#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005602#ifdef TMP_MAX
5603 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5604#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005605#ifdef WNOHANG
5606 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5607#endif
5608#ifdef O_RDONLY
5609 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5610#endif
5611#ifdef O_WRONLY
5612 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5613#endif
5614#ifdef O_RDWR
5615 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5616#endif
5617#ifdef O_NDELAY
5618 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5619#endif
5620#ifdef O_NONBLOCK
5621 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5622#endif
5623#ifdef O_APPEND
5624 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5625#endif
5626#ifdef O_DSYNC
5627 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5628#endif
5629#ifdef O_RSYNC
5630 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5631#endif
5632#ifdef O_SYNC
5633 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5634#endif
5635#ifdef O_NOCTTY
5636 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5637#endif
5638#ifdef O_CREAT
5639 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5640#endif
5641#ifdef O_EXCL
5642 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5643#endif
5644#ifdef O_TRUNC
5645 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5646#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005647#ifdef O_BINARY
5648 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5649#endif
5650#ifdef O_TEXT
5651 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5652#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005653
Guido van Rossum246bc171999-02-01 23:54:31 +00005654#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005655 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5656 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5657 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5658 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5659 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005660#endif
5661
Guido van Rossumd48f2521997-12-05 22:19:34 +00005662#if defined(PYOS_OS2)
5663 if (insertvalues(d)) return -1;
5664#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005665 return 0;
5666}
5667
5668
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005669#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005670#define INITFUNC initnt
5671#define MODNAME "nt"
5672#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005673#if defined(PYOS_OS2)
5674#define INITFUNC initos2
5675#define MODNAME "os2"
5676#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005677#define INITFUNC initposix
5678#define MODNAME "posix"
5679#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005680#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005681
Guido van Rossum3886bb61998-12-04 18:50:17 +00005682DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005683INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005684{
Barry Warsaw53699e91996-12-10 23:23:01 +00005685 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005686
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005687 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005688 posix_methods,
5689 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005690 (PyObject *)NULL,
5691 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005692 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005693
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005694 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005695 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005696 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005697 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005698 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005699
Barry Warsaw4a342091996-12-19 23:50:02 +00005700 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005701 return;
5702
Fred Drakebec628d1999-12-15 18:31:10 +00005703 if (setup_confname_tables(d))
5704 return;
5705
Barry Warsawca74da41999-02-09 19:31:45 +00005706 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005707
Guido van Rossumb3d39562000-01-31 18:41:26 +00005708#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005709 if (posix_putenv_garbage == NULL)
5710 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005711#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005712}