blob: 5575b9feb96fa78bb277ba56e035e00b88a9cb34 [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
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000357#ifdef MS_WIN32
358static PyObject *
359win32_error(char* function, char* filename)
360{
Mark Hammond33a6da92000-08-15 00:46:38 +0000361 /* XXX We should pass the function name along in the future.
362 (_winreg.c also wants to pass the function name.)
363 This would however require an additional param to the
364 Windows error object, which is non-trivial.
365 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000366 errno = GetLastError();
367 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000368 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000369 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000370 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000371}
372#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000373
Guido van Rossumd48f2521997-12-05 22:19:34 +0000374#if defined(PYOS_OS2)
375/**********************************************************************
376 * Helper Function to Trim and Format OS/2 Messages
377 **********************************************************************/
378 static void
379os2_formatmsg(char *msgbuf, int msglen, char *reason)
380{
381 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
382
383 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
384 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
385
386 while (lastc > msgbuf && isspace(*lastc))
387 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
388 }
389
390 /* Add Optional Reason Text */
391 if (reason) {
392 strcat(msgbuf, " : ");
393 strcat(msgbuf, reason);
394 }
395}
396
397/**********************************************************************
398 * Decode an OS/2 Operating System Error Code
399 *
400 * A convenience function to lookup an OS/2 error code and return a
401 * text message we can use to raise a Python exception.
402 *
403 * Notes:
404 * The messages for errors returned from the OS/2 kernel reside in
405 * the file OSO001.MSG in the \OS2 directory hierarchy.
406 *
407 **********************************************************************/
408 static char *
409os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
410{
411 APIRET rc;
412 ULONG msglen;
413
414 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
415 Py_BEGIN_ALLOW_THREADS
416 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
417 errorcode, "oso001.msg", &msglen);
418 Py_END_ALLOW_THREADS
419
420 if (rc == NO_ERROR)
421 os2_formatmsg(msgbuf, msglen, reason);
422 else
423 sprintf(msgbuf, "unknown OS error #%d", errorcode);
424
425 return msgbuf;
426}
427
428/* Set an OS/2-specific error and return NULL. OS/2 kernel
429 errors are not in a global variable e.g. 'errno' nor are
430 they congruent with posix error numbers. */
431
432static PyObject * os2_error(int code)
433{
434 char text[1024];
435 PyObject *v;
436
437 os2_strerror(text, sizeof(text), code, "");
438
439 v = Py_BuildValue("(is)", code, text);
440 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000441 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000442 Py_DECREF(v);
443 }
444 return NULL; /* Signal to Python that an Exception is Pending */
445}
446
447#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000448
449/* POSIX generic methods */
450
Barry Warsaw53699e91996-12-10 23:23:01 +0000451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000452posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000453{
454 int fd;
455 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000456 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000457 return NULL;
458 Py_BEGIN_ALLOW_THREADS
459 res = (*func)(fd);
460 Py_END_ALLOW_THREADS
461 if (res < 0)
462 return posix_error();
463 Py_INCREF(Py_None);
464 return Py_None;
465}
466
467
468static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000469posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000470{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000471 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000472 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000473 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000474 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000475 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000476 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000477 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000478 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000479 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000480 Py_INCREF(Py_None);
481 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482}
483
Barry Warsaw53699e91996-12-10 23:23:01 +0000484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000485posix_2str(PyObject *args, char *format,
486 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000488 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000489 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000490 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000491 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000492 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000493 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000494 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000495 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000496 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000498 Py_INCREF(Py_None);
499 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500}
501
Fred Drake699f3522000-06-29 21:12:41 +0000502/* pack a system stat C structure into the Python stat tuple
503 (used by posix_stat() and posix_fstat()) */
504static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000505_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000506{
507 PyObject *v = PyTuple_New(10);
508 if (v == NULL)
509 return NULL;
510
511 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
512#ifdef HAVE_LARGEFILE_SUPPORT
513 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
514#else
515 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
516#endif
517#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
518 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
519#else
520 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
521#endif
522 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
523 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
524 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
525#ifdef HAVE_LARGEFILE_SUPPORT
526 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
527#else
528 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
529#endif
530#if SIZEOF_TIME_T > SIZEOF_LONG
531 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
532 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
533 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
534#else
535 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
536 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
537 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
538#endif
539
540 if (PyErr_Occurred()) {
541 Py_DECREF(v);
542 return NULL;
543 }
544
545 return v;
546}
547
548
Barry Warsaw53699e91996-12-10 23:23:01 +0000549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000550posix_do_stat(PyObject *self, PyObject *args, char *format,
551 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000552{
Fred Drake699f3522000-06-29 21:12:41 +0000553 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000554 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000555 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000556
557#ifdef MS_WIN32
558 int pathlen;
559 char pathcopy[MAX_PATH];
560#endif /* MS_WIN32 */
561
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000562 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000563 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000564
565#ifdef MS_WIN32
566 pathlen = strlen(path);
567 /* the library call can blow up if the file name is too long! */
568 if (pathlen > MAX_PATH) {
569 errno = ENAMETOOLONG;
570 return posix_error();
571 }
572
573 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000574 /* exception for specific or current drive root */
575 if (!((pathlen == 1) ||
576 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000577 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000578 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000579 {
580 strncpy(pathcopy, path, pathlen);
581 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
582 path = pathcopy;
583 }
584 }
585#endif /* MS_WIN32 */
586
Barry Warsaw53699e91996-12-10 23:23:01 +0000587 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000588 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000589 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000590 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000591 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000592
593 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000594}
595
596
597/* POSIX methods */
598
Guido van Rossum94f6f721999-01-06 18:42:14 +0000599static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000600"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000601Test for access to a file.";
602
603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000604posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000605{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000606 char *path;
607 int mode;
608 int res;
609
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000610 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000611 return NULL;
612 Py_BEGIN_ALLOW_THREADS
613 res = access(path, mode);
614 Py_END_ALLOW_THREADS
615 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000616}
617
Guido van Rossumd371ff11999-01-25 16:12:23 +0000618#ifndef F_OK
619#define F_OK 0
620#endif
621#ifndef R_OK
622#define R_OK 4
623#endif
624#ifndef W_OK
625#define W_OK 2
626#endif
627#ifndef X_OK
628#define X_OK 1
629#endif
630
631#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000632static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000633"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000634Return the name of the terminal device connected to 'fd'.";
635
636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000637posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000638{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000639 int id;
640 char *ret;
641
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000642 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000643 return NULL;
644
Guido van Rossum94f6f721999-01-06 18:42:14 +0000645 ret = ttyname(id);
646 if (ret == NULL)
647 return(posix_error());
648 return(PyString_FromString(ret));
649}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000650#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000651
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000652#ifdef HAVE_CTERMID
653static char posix_ctermid__doc__[] =
654"ctermid() -> String\n\
655Return the name of the controlling terminal for this process.";
656
657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000658posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000659{
660 char *ret;
661 char buffer[L_ctermid];
662
663 if (!PyArg_ParseTuple(args, ":ctermid"))
664 return NULL;
665
Greg Wardb48bc172000-03-01 21:51:56 +0000666#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000667 ret = ctermid_r(buffer);
668#else
669 ret = ctermid(buffer);
670#endif
671 if (ret == NULL)
672 return(posix_error());
673 return(PyString_FromString(buffer));
674}
675#endif
676
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000677static char posix_chdir__doc__[] =
678"chdir(path) -> None\n\
679Change the current working directory to the specified path.";
680
Barry Warsaw53699e91996-12-10 23:23:01 +0000681static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000682posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000683{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000684 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000685}
686
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000687
688static char posix_chmod__doc__[] =
689"chmod(path, mode) -> None\n\
690Change the access permissions of a file.";
691
Barry Warsaw53699e91996-12-10 23:23:01 +0000692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000693posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000695 char *path;
696 int i;
697 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000698 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000699 return NULL;
700 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000701 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000702 Py_END_ALLOW_THREADS
703 if (res < 0)
704 return posix_error_with_filename(path);
705 Py_INCREF(Py_None);
706 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000707}
708
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000709
Guido van Rossum21142a01999-01-08 21:05:37 +0000710#ifdef HAVE_FSYNC
711static char posix_fsync__doc__[] =
712"fsync(fildes) -> None\n\
713force write of file with filedescriptor to disk.";
714
715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000716posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000717{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000718 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000719}
720#endif /* HAVE_FSYNC */
721
722#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000723
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000724#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000725extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
726#endif
727
Guido van Rossum21142a01999-01-08 21:05:37 +0000728static char posix_fdatasync__doc__[] =
729"fdatasync(fildes) -> None\n\
730force write of file with filedescriptor to disk.\n\
731 does not force update of metadata.";
732
733static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000734posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000735{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000736 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000737}
738#endif /* HAVE_FDATASYNC */
739
740
Fredrik Lundh10723342000-07-10 16:38:09 +0000741#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000742static char posix_chown__doc__[] =
743"chown(path, uid, gid) -> None\n\
744Change the owner and group id of path to the numeric uid and gid.";
745
Barry Warsaw53699e91996-12-10 23:23:01 +0000746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000747posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000748{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000749 char *path;
750 int uid, gid;
751 int res;
752 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
753 return NULL;
754 Py_BEGIN_ALLOW_THREADS
755 res = chown(path, (uid_t) uid, (gid_t) gid);
756 Py_END_ALLOW_THREADS
757 if (res < 0)
758 return posix_error_with_filename(path);
759 Py_INCREF(Py_None);
760 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000761}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000762#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000763
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000764
Guido van Rossum36bc6801995-06-14 22:54:23 +0000765#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000766static char posix_getcwd__doc__[] =
767"getcwd() -> path\n\
768Return a string representing the current working directory.";
769
Barry Warsaw53699e91996-12-10 23:23:01 +0000770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000771posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000772{
773 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000774 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000775 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000777 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000778 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000779 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000780 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000781 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000782 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000783}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000784#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000786
Guido van Rossumb6775db1994-08-01 11:34:53 +0000787#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000788static char posix_link__doc__[] =
789"link(src, dst) -> None\n\
790Create a hard link to a file.";
791
Barry Warsaw53699e91996-12-10 23:23:01 +0000792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000793posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000794{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000795 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000796}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000797#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000798
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000799
800static char posix_listdir__doc__[] =
801"listdir(path) -> list_of_strings\n\
802Return a list containing the names of the entries in the directory.\n\
803\n\
804 path: path of directory to list\n\
805\n\
806The list is in arbitrary order. It does not include the special\n\
807entries '.' and '..' even if they are present in the directory.";
808
Barry Warsaw53699e91996-12-10 23:23:01 +0000809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000810posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000811{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000812 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000813 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000814#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000815
Guido van Rossumb6775db1994-08-01 11:34:53 +0000816 char *name;
817 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000818 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000819 HANDLE hFindFile;
820 WIN32_FIND_DATA FileData;
821 char namebuf[MAX_PATH+5];
Tim Peters0bb44a42000-09-15 07:44:49 +0000822 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000823
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000824 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000825 return NULL;
826 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000827 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000828 return NULL;
829 }
830 strcpy(namebuf, name);
Tim Peters0bb44a42000-09-15 07:44:49 +0000831 ch = namebuf[len-1];
832 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000833 namebuf[len++] = '/';
834 strcpy(namebuf + len, "*.*");
835
Barry Warsaw53699e91996-12-10 23:23:01 +0000836 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000837 return NULL;
838
839 hFindFile = FindFirstFile(namebuf, &FileData);
840 if (hFindFile == INVALID_HANDLE_VALUE) {
841 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000842 if (errno == ERROR_FILE_NOT_FOUND)
843 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000844 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000845 }
846 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000847 if (FileData.cFileName[0] == '.' &&
848 (FileData.cFileName[1] == '\0' ||
849 FileData.cFileName[1] == '.' &&
850 FileData.cFileName[2] == '\0'))
851 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000852 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000853 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000854 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000855 d = NULL;
856 break;
857 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000858 if (PyList_Append(d, v) != 0) {
859 Py_DECREF(v);
860 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000861 d = NULL;
862 break;
863 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000864 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000865 } while (FindNextFile(hFindFile, &FileData) == TRUE);
866
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000867 if (FindClose(hFindFile) == FALSE)
868 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000869
870 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000871
Tim Peters0bb44a42000-09-15 07:44:49 +0000872#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000873
874#ifndef MAX_PATH
875#define MAX_PATH 250
876#endif
877 char *name, *pt;
878 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000879 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000880 char namebuf[MAX_PATH+5];
881 struct _find_t ep;
882
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000883 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000884 return NULL;
885 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000886 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000887 return NULL;
888 }
889 strcpy(namebuf, name);
890 for (pt = namebuf; *pt; pt++)
891 if (*pt == '/')
892 *pt = '\\';
893 if (namebuf[len-1] != '\\')
894 namebuf[len++] = '\\';
895 strcpy(namebuf + len, "*.*");
896
Barry Warsaw53699e91996-12-10 23:23:01 +0000897 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000898 return NULL;
899
900 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000901 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
902 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000903 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000904 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000905 }
906 do {
907 if (ep.name[0] == '.' &&
908 (ep.name[1] == '\0' ||
909 ep.name[1] == '.' &&
910 ep.name[2] == '\0'))
911 continue;
912 strcpy(namebuf, ep.name);
913 for (pt = namebuf; *pt; pt++)
914 if (isupper(*pt))
915 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000916 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000917 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000918 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000919 d = NULL;
920 break;
921 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000922 if (PyList_Append(d, v) != 0) {
923 Py_DECREF(v);
924 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000925 d = NULL;
926 break;
927 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000928 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000929 } while (_dos_findnext(&ep) == 0);
930
931 return d;
932
Tim Peters0bb44a42000-09-15 07:44:49 +0000933#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000934
935#ifndef MAX_PATH
936#define MAX_PATH CCHMAXPATH
937#endif
938 char *name, *pt;
939 int len;
940 PyObject *d, *v;
941 char namebuf[MAX_PATH+5];
942 HDIR hdir = 1;
943 ULONG srchcnt = 1;
944 FILEFINDBUF3 ep;
945 APIRET rc;
946
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000947 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000948 return NULL;
949 if (len >= MAX_PATH) {
950 PyErr_SetString(PyExc_ValueError, "path too long");
951 return NULL;
952 }
953 strcpy(namebuf, name);
954 for (pt = namebuf; *pt; pt++)
955 if (*pt == '/')
956 *pt = '\\';
957 if (namebuf[len-1] != '\\')
958 namebuf[len++] = '\\';
959 strcpy(namebuf + len, "*.*");
960
961 if ((d = PyList_New(0)) == NULL)
962 return NULL;
963
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000964 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
965 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000966 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000967 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
968 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
969 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000970
971 if (rc != NO_ERROR) {
972 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000973 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000974 }
975
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000976 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000977 do {
978 if (ep.achName[0] == '.'
979 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000980 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000981
982 strcpy(namebuf, ep.achName);
983
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000984 /* Leave Case of Name Alone -- In Native Form */
985 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000986
987 v = PyString_FromString(namebuf);
988 if (v == NULL) {
989 Py_DECREF(d);
990 d = NULL;
991 break;
992 }
993 if (PyList_Append(d, v) != 0) {
994 Py_DECREF(v);
995 Py_DECREF(d);
996 d = NULL;
997 break;
998 }
999 Py_DECREF(v);
1000 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1001 }
1002
1003 return d;
1004#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001005
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001006 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001007 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001008 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001009 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001010 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001011 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001012 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001013 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001014 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001015 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001016 closedir(dirp);
1017 return NULL;
1018 }
1019 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001020 if (ep->d_name[0] == '.' &&
1021 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001022 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001023 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001024 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001025 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001026 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001027 d = NULL;
1028 break;
1029 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001030 if (PyList_Append(d, v) != 0) {
1031 Py_DECREF(v);
1032 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001033 d = NULL;
1034 break;
1035 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001036 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001037 }
1038 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001039
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001040 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001041
Tim Peters0bb44a42000-09-15 07:44:49 +00001042#endif /* which OS */
1043} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001044
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001045static char posix_mkdir__doc__[] =
1046"mkdir(path [, mode=0777]) -> None\n\
1047Create a directory.";
1048
Barry Warsaw53699e91996-12-10 23:23:01 +00001049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001050posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001051{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001052 int res;
1053 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001054 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001055 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001056 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001057 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001058#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001059 res = mkdir(path);
1060#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001061 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001062#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001063 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001064 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001065 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001066 Py_INCREF(Py_None);
1067 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001068}
1069
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001070
Guido van Rossumb6775db1994-08-01 11:34:53 +00001071#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001072static char posix_nice__doc__[] =
1073"nice(inc) -> new_priority\n\
1074Decrease the priority of process and return new priority.";
1075
Barry Warsaw53699e91996-12-10 23:23:01 +00001076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001077posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001078{
1079 int increment, value;
1080
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001081 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001082 return NULL;
1083 value = nice(increment);
1084 if (value == -1)
1085 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001086 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001087}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001088#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001090
1091static char posix_rename__doc__[] =
1092"rename(old, new) -> None\n\
1093Rename a file or directory.";
1094
Barry Warsaw53699e91996-12-10 23:23:01 +00001095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001096posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001097{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001098 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001099}
1100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001101
1102static char posix_rmdir__doc__[] =
1103"rmdir(path) -> None\n\
1104Remove a directory.";
1105
Barry Warsaw53699e91996-12-10 23:23:01 +00001106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001107posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001108{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001109 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001110}
1111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001112
1113static char posix_stat__doc__[] =
1114"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1115Perform a stat system call on the given path.";
1116
Barry Warsaw53699e91996-12-10 23:23:01 +00001117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001118posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119{
Fred Drake699f3522000-06-29 21:12:41 +00001120 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001121}
1122
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001123
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001124#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001125static char posix_system__doc__[] =
1126"system(command) -> exit_status\n\
1127Execute the command (a string) in a subshell.";
1128
Barry Warsaw53699e91996-12-10 23:23:01 +00001129static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001130posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001131{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001132 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001133 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001134 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001136 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001137 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001138 Py_END_ALLOW_THREADS
1139 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001140}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001141#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001143
1144static char posix_umask__doc__[] =
1145"umask(new_mask) -> old_mask\n\
1146Set the current numeric umask and return the previous umask.";
1147
Barry Warsaw53699e91996-12-10 23:23:01 +00001148static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001149posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150{
1151 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001152 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153 return NULL;
1154 i = umask(i);
1155 if (i < 0)
1156 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001157 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001158}
1159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001160
1161static char posix_unlink__doc__[] =
1162"unlink(path) -> None\n\
1163Remove a file (same as remove(path)).";
1164
1165static char posix_remove__doc__[] =
1166"remove(path) -> None\n\
1167Remove a file (same as unlink(path)).";
1168
Barry Warsaw53699e91996-12-10 23:23:01 +00001169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001170posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001172 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001173}
1174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001175
Guido van Rossumb6775db1994-08-01 11:34:53 +00001176#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001177static char posix_uname__doc__[] =
1178"uname() -> (sysname, nodename, release, version, machine)\n\
1179Return a tuple identifying the current operating system.";
1180
Barry Warsaw53699e91996-12-10 23:23:01 +00001181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001182posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001183{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001184 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001185 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001186 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001187 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001188 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001189 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001190 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001191 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001192 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001193 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001194 u.sysname,
1195 u.nodename,
1196 u.release,
1197 u.version,
1198 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001199}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001200#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001202
1203static char posix_utime__doc__[] =
1204"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001205utime(path, None) -> None\n\
1206Set the access and modified time of the file to the given values. If the\n\
1207second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001208
Barry Warsaw53699e91996-12-10 23:23:01 +00001209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001210posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001212 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001213 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001214 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001215 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001216
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001217/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001218#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001219 struct utimbuf buf;
1220#define ATIME buf.actime
1221#define MTIME buf.modtime
1222#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001223#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001224 time_t buf[2];
1225#define ATIME buf[0]
1226#define MTIME buf[1]
1227#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001228#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001229
Barry Warsaw3cef8562000-05-01 16:17:24 +00001230 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001231 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001232 if (arg == Py_None) {
1233 /* optional time values not given */
1234 Py_BEGIN_ALLOW_THREADS
1235 res = utime(path, NULL);
1236 Py_END_ALLOW_THREADS
1237 }
1238 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1239 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001240 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001241 return NULL;
1242 }
1243 else {
1244 ATIME = atime;
1245 MTIME = mtime;
1246 Py_BEGIN_ALLOW_THREADS
1247 res = utime(path, UTIME_ARG);
1248 Py_END_ALLOW_THREADS
1249 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001250 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001251 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001252 Py_INCREF(Py_None);
1253 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001254#undef UTIME_ARG
1255#undef ATIME
1256#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001257}
1258
Guido van Rossum85e3b011991-06-03 12:42:10 +00001259
Guido van Rossum3b066191991-06-04 19:40:25 +00001260/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001262static char posix__exit__doc__[] =
1263"_exit(status)\n\
1264Exit to the system with specified status, without normal exit processing.";
1265
Barry Warsaw53699e91996-12-10 23:23:01 +00001266static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001267posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001268{
1269 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001270 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001271 return NULL;
1272 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001273 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001274}
1275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001276
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001277#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001278static char posix_execv__doc__[] =
1279"execv(path, args)\n\
1280Execute an executable path with arguments, replacing current process.\n\
1281\n\
1282 path: path of executable file\n\
1283 args: tuple or list of strings";
1284
Barry Warsaw53699e91996-12-10 23:23:01 +00001285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001286posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001287{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001288 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001289 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001290 char **argvlist;
1291 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001292 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001293
Guido van Rossum89b33251993-10-22 14:26:06 +00001294 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001295 argv is a list or tuple of strings. */
1296
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001297 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001298 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001299 if (PyList_Check(argv)) {
1300 argc = PyList_Size(argv);
1301 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001302 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001303 else if (PyTuple_Check(argv)) {
1304 argc = PyTuple_Size(argv);
1305 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001306 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001307 else {
Fred Drake661ea262000-10-24 19:57:45 +00001308 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001309 return NULL;
1310 }
1311
1312 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001313 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001314 return NULL;
1315 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001316
Barry Warsaw53699e91996-12-10 23:23:01 +00001317 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001318 if (argvlist == NULL)
1319 return NULL;
1320 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001321 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1322 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001323 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001324 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001325 return NULL;
1326
Guido van Rossum85e3b011991-06-03 12:42:10 +00001327 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001328 }
1329 argvlist[argc] = NULL;
1330
Guido van Rossumb6775db1994-08-01 11:34:53 +00001331#ifdef BAD_EXEC_PROTOTYPES
1332 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001333#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001334 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001335#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001336
Guido van Rossum85e3b011991-06-03 12:42:10 +00001337 /* If we get here it's definitely an error */
1338
Barry Warsaw53699e91996-12-10 23:23:01 +00001339 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001340 return posix_error();
1341}
1342
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001343
1344static char posix_execve__doc__[] =
1345"execve(path, args, env)\n\
1346Execute a path with arguments and environment, replacing current process.\n\
1347\n\
1348 path: path of executable file\n\
1349 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001350 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001351
Barry Warsaw53699e91996-12-10 23:23:01 +00001352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001353posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001354{
1355 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001356 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001357 char **argvlist;
1358 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001359 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001360 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001361 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001362
1363 /* execve has three arguments: (path, argv, env), where
1364 argv is a list or tuple of strings and env is a dictionary
1365 like posix.environ. */
1366
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001367 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001368 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001369 if (PyList_Check(argv)) {
1370 argc = PyList_Size(argv);
1371 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001372 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001373 else if (PyTuple_Check(argv)) {
1374 argc = PyTuple_Size(argv);
1375 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001376 }
1377 else {
Fred Drake661ea262000-10-24 19:57:45 +00001378 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001379 return NULL;
1380 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001381 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001382 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001383 return NULL;
1384 }
1385
Guido van Rossum50422b42000-04-26 20:34:28 +00001386 if (argc == 0) {
1387 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001388 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001389 return NULL;
1390 }
1391
Barry Warsaw53699e91996-12-10 23:23:01 +00001392 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001393 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001394 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001395 return NULL;
1396 }
1397 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001398 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001399 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001400 &argvlist[i]))
1401 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001402 goto fail_1;
1403 }
1404 }
1405 argvlist[argc] = NULL;
1406
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001407 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001408 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001409 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001410 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001411 goto fail_1;
1412 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001413 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001414 keys = PyMapping_Keys(env);
1415 vals = PyMapping_Values(env);
1416 if (!keys || !vals)
1417 goto fail_2;
1418
1419 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001420 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001421
1422 key = PyList_GetItem(keys, pos);
1423 val = PyList_GetItem(vals, pos);
1424 if (!key || !val)
1425 goto fail_2;
1426
Fred Drake661ea262000-10-24 19:57:45 +00001427 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1428 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001429 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001430 goto fail_2;
1431 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001432
1433#if defined(PYOS_OS2)
1434 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1435 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1436#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001437 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001438 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001439 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001440 goto fail_2;
1441 }
1442 sprintf(p, "%s=%s", k, v);
1443 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001444#if defined(PYOS_OS2)
1445 }
1446#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001447 }
1448 envlist[envc] = 0;
1449
Guido van Rossumb6775db1994-08-01 11:34:53 +00001450
1451#ifdef BAD_EXEC_PROTOTYPES
1452 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001453#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001454 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001455#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001456
1457 /* If we get here it's definitely an error */
1458
1459 (void) posix_error();
1460
1461 fail_2:
1462 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001463 PyMem_DEL(envlist[envc]);
1464 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001465 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001466 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001467 Py_XDECREF(vals);
1468 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001469 return NULL;
1470}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001471#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001472
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001473
Guido van Rossuma1065681999-01-25 23:20:23 +00001474#ifdef HAVE_SPAWNV
1475static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001476"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001477Execute an executable path with arguments, replacing current process.\n\
1478\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001479 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001480 path: path of executable file\n\
1481 args: tuple or list of strings";
1482
1483static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001484posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001485{
1486 char *path;
1487 PyObject *argv;
1488 char **argvlist;
1489 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001490 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001491 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001492
1493 /* spawnv has three arguments: (mode, path, argv), where
1494 argv is a list or tuple of strings. */
1495
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001496 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001497 return NULL;
1498 if (PyList_Check(argv)) {
1499 argc = PyList_Size(argv);
1500 getitem = PyList_GetItem;
1501 }
1502 else if (PyTuple_Check(argv)) {
1503 argc = PyTuple_Size(argv);
1504 getitem = PyTuple_GetItem;
1505 }
1506 else {
Fred Drake661ea262000-10-24 19:57:45 +00001507 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001508 return NULL;
1509 }
1510
1511 argvlist = PyMem_NEW(char *, argc+1);
1512 if (argvlist == NULL)
1513 return NULL;
1514 for (i = 0; i < argc; i++) {
1515 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1516 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001517 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001518 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001519 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001520 }
1521 }
1522 argvlist[argc] = NULL;
1523
Guido van Rossum246bc171999-02-01 23:54:31 +00001524 if (mode == _OLD_P_OVERLAY)
1525 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001526 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001527
1528 PyMem_DEL(argvlist);
1529
Fred Drake699f3522000-06-29 21:12:41 +00001530 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001531 return posix_error();
1532 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001533#if SIZEOF_LONG == SIZEOF_VOID_P
1534 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001535#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001536 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001537#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001538}
1539
1540
1541static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001542"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001543Execute a path with arguments and environment, replacing current process.\n\
1544\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001545 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001546 path: path of executable file\n\
1547 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001548 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001549
1550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001551posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001552{
1553 char *path;
1554 PyObject *argv, *env;
1555 char **argvlist;
1556 char **envlist;
1557 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1558 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001559 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001560 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001561
1562 /* spawnve has four arguments: (mode, path, argv, env), where
1563 argv is a list or tuple of strings and env is a dictionary
1564 like posix.environ. */
1565
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001566 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001567 return NULL;
1568 if (PyList_Check(argv)) {
1569 argc = PyList_Size(argv);
1570 getitem = PyList_GetItem;
1571 }
1572 else if (PyTuple_Check(argv)) {
1573 argc = PyTuple_Size(argv);
1574 getitem = PyTuple_GetItem;
1575 }
1576 else {
Fred Drake661ea262000-10-24 19:57:45 +00001577 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001578 return NULL;
1579 }
1580 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001581 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001582 return NULL;
1583 }
1584
1585 argvlist = PyMem_NEW(char *, argc+1);
1586 if (argvlist == NULL) {
1587 PyErr_NoMemory();
1588 return NULL;
1589 }
1590 for (i = 0; i < argc; i++) {
1591 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001592 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001593 &argvlist[i]))
1594 {
1595 goto fail_1;
1596 }
1597 }
1598 argvlist[argc] = NULL;
1599
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001600 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001601 envlist = PyMem_NEW(char *, i + 1);
1602 if (envlist == NULL) {
1603 PyErr_NoMemory();
1604 goto fail_1;
1605 }
1606 envc = 0;
1607 keys = PyMapping_Keys(env);
1608 vals = PyMapping_Values(env);
1609 if (!keys || !vals)
1610 goto fail_2;
1611
1612 for (pos = 0; pos < i; pos++) {
1613 char *p, *k, *v;
1614
1615 key = PyList_GetItem(keys, pos);
1616 val = PyList_GetItem(vals, pos);
1617 if (!key || !val)
1618 goto fail_2;
1619
Fred Drake661ea262000-10-24 19:57:45 +00001620 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1621 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001622 {
1623 goto fail_2;
1624 }
1625 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1626 if (p == NULL) {
1627 PyErr_NoMemory();
1628 goto fail_2;
1629 }
1630 sprintf(p, "%s=%s", k, v);
1631 envlist[envc++] = p;
1632 }
1633 envlist[envc] = 0;
1634
Guido van Rossum246bc171999-02-01 23:54:31 +00001635 if (mode == _OLD_P_OVERLAY)
1636 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001637 spawnval = _spawnve(mode, path, argvlist, envlist);
1638 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001639 (void) posix_error();
1640 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001641#if SIZEOF_LONG == SIZEOF_VOID_P
1642 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001643#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001644 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001645#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001646
1647 fail_2:
1648 while (--envc >= 0)
1649 PyMem_DEL(envlist[envc]);
1650 PyMem_DEL(envlist);
1651 fail_1:
1652 PyMem_DEL(argvlist);
1653 Py_XDECREF(vals);
1654 Py_XDECREF(keys);
1655 return res;
1656}
1657#endif /* HAVE_SPAWNV */
1658
1659
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001660#ifdef HAVE_FORK1
1661static char posix_fork1__doc__[] =
1662"fork1() -> pid\n\
1663Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1664\n\
1665Return 0 to child process and PID of child to parent process.";
1666
1667static PyObject *
1668posix_fork1(self, args)
1669 PyObject *self;
1670 PyObject *args;
1671{
1672 int pid;
1673 if (!PyArg_ParseTuple(args, ":fork1"))
1674 return NULL;
1675 pid = fork1();
1676 if (pid == -1)
1677 return posix_error();
1678 PyOS_AfterFork();
1679 return PyInt_FromLong((long)pid);
1680}
1681#endif
1682
1683
Guido van Rossumad0ee831995-03-01 10:34:45 +00001684#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001685static char posix_fork__doc__[] =
1686"fork() -> pid\n\
1687Fork a child process.\n\
1688\n\
1689Return 0 to child process and PID of child to parent process.";
1690
Barry Warsaw53699e91996-12-10 23:23:01 +00001691static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001692posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001693{
1694 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001695 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001696 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001697 pid = fork();
1698 if (pid == -1)
1699 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001700 if (pid == 0)
1701 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001702 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001703}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001704#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001705
Fred Drake8cef4cf2000-06-28 16:40:38 +00001706#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1707#ifdef HAVE_PTY_H
1708#include <pty.h>
1709#else
1710#ifdef HAVE_LIBUTIL_H
1711#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001712#endif /* HAVE_LIBUTIL_H */
1713#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001714#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001715
Thomas Wouters70c21a12000-07-14 14:28:33 +00001716#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001717static char posix_openpty__doc__[] =
1718"openpty() -> (master_fd, slave_fd)\n\
1719Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1720
1721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001722posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001723{
1724 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001725#ifndef HAVE_OPENPTY
1726 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001727#endif
1728
Fred Drake8cef4cf2000-06-28 16:40:38 +00001729 if (!PyArg_ParseTuple(args, ":openpty"))
1730 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001731
1732#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001733 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1734 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001735#else
1736 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1737 if (slave_name == NULL)
1738 return posix_error();
1739
1740 slave_fd = open(slave_name, O_RDWR);
1741 if (slave_fd < 0)
1742 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001743#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001744
Fred Drake8cef4cf2000-06-28 16:40:38 +00001745 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001746
Fred Drake8cef4cf2000-06-28 16:40:38 +00001747}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001748#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001749
1750#ifdef HAVE_FORKPTY
1751static char posix_forkpty__doc__[] =
1752"forkpty() -> (pid, master_fd)\n\
1753Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1754Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1755To both, return fd of newly opened pseudo-terminal.\n";
1756
1757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001758posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001759{
1760 int master_fd, pid;
1761
1762 if (!PyArg_ParseTuple(args, ":forkpty"))
1763 return NULL;
1764 pid = forkpty(&master_fd, NULL, NULL, NULL);
1765 if (pid == -1)
1766 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001767 if (pid == 0)
1768 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001769 return Py_BuildValue("(ii)", pid, master_fd);
1770}
1771#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001772
Guido van Rossumad0ee831995-03-01 10:34:45 +00001773#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001774static char posix_getegid__doc__[] =
1775"getegid() -> egid\n\
1776Return the current process's effective group id.";
1777
Barry Warsaw53699e91996-12-10 23:23:01 +00001778static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001779posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001780{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001781 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001782 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001783 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001784}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001785#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001787
Guido van Rossumad0ee831995-03-01 10:34:45 +00001788#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001789static char posix_geteuid__doc__[] =
1790"geteuid() -> euid\n\
1791Return the current process's effective user id.";
1792
Barry Warsaw53699e91996-12-10 23:23:01 +00001793static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001794posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001795{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001796 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001797 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001798 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001799}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001800#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001801
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001802
Guido van Rossumad0ee831995-03-01 10:34:45 +00001803#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001804static char posix_getgid__doc__[] =
1805"getgid() -> gid\n\
1806Return the current process's group id.";
1807
Barry Warsaw53699e91996-12-10 23:23:01 +00001808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001809posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001810{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001811 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001812 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001813 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001814}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001815#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001816
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001817
1818static char posix_getpid__doc__[] =
1819"getpid() -> pid\n\
1820Return the current process id";
1821
Barry Warsaw53699e91996-12-10 23:23:01 +00001822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001823posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001824{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001825 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001826 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001827 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001828}
1829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001830
Fred Drakec9680921999-12-13 16:37:25 +00001831#ifdef HAVE_GETGROUPS
1832static char posix_getgroups__doc__[] = "\
1833getgroups() -> list of group IDs\n\
1834Return list of supplemental group IDs for the process.";
1835
1836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001837posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001838{
1839 PyObject *result = NULL;
1840
1841 if (PyArg_ParseTuple(args, ":getgroups")) {
1842#ifdef NGROUPS_MAX
1843#define MAX_GROUPS NGROUPS_MAX
1844#else
1845 /* defined to be 16 on Solaris7, so this should be a small number */
1846#define MAX_GROUPS 64
1847#endif
1848 gid_t grouplist[MAX_GROUPS];
1849 int n;
1850
1851 n = getgroups(MAX_GROUPS, grouplist);
1852 if (n < 0)
1853 posix_error();
1854 else {
1855 result = PyList_New(n);
1856 if (result != NULL) {
1857 PyObject *o;
1858 int i;
1859 for (i = 0; i < n; ++i) {
1860 o = PyInt_FromLong((long)grouplist[i]);
1861 if (o == NULL) {
1862 Py_DECREF(result);
1863 result = NULL;
1864 break;
1865 }
1866 PyList_SET_ITEM(result, i, o);
1867 }
1868 }
1869 }
1870 }
1871 return result;
1872}
1873#endif
1874
Guido van Rossumb6775db1994-08-01 11:34:53 +00001875#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001876static char posix_getpgrp__doc__[] =
1877"getpgrp() -> pgrp\n\
1878Return the current process group id.";
1879
Barry Warsaw53699e91996-12-10 23:23:01 +00001880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001881posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001882{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001883 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001884 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001885#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001886 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001887#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001888 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001889#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001890}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001891#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001892
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001893
Guido van Rossumb6775db1994-08-01 11:34:53 +00001894#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001895static char posix_setpgrp__doc__[] =
1896"setpgrp() -> None\n\
1897Make this process a session leader.";
1898
Barry Warsaw53699e91996-12-10 23:23:01 +00001899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001900posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001901{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001902 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001903 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001904#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001905 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001906#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001907 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001908#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001909 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001910 Py_INCREF(Py_None);
1911 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001912}
1913
Guido van Rossumb6775db1994-08-01 11:34:53 +00001914#endif /* HAVE_SETPGRP */
1915
Guido van Rossumad0ee831995-03-01 10:34:45 +00001916#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001917static char posix_getppid__doc__[] =
1918"getppid() -> ppid\n\
1919Return the parent's process id.";
1920
Barry Warsaw53699e91996-12-10 23:23:01 +00001921static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001922posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001923{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001924 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001925 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001926 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001927}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001928#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001929
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001930
Fred Drake12c6e2d1999-12-14 21:25:03 +00001931#ifdef HAVE_GETLOGIN
1932static char posix_getlogin__doc__[] = "\
1933getlogin() -> string\n\
1934Return the actual login name.";
1935
1936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001937posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001938{
1939 PyObject *result = NULL;
1940
1941 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00001942 char *name;
1943 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001944
Fred Drakea30680b2000-12-06 21:24:28 +00001945 errno = 0;
1946 name = getlogin();
1947 if (name == NULL) {
1948 if (errno)
1949 posix_error();
1950 else
1951 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00001952 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00001953 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00001954 else
1955 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00001956 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00001957 }
1958 return result;
1959}
1960#endif
1961
Guido van Rossumad0ee831995-03-01 10:34:45 +00001962#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001963static char posix_getuid__doc__[] =
1964"getuid() -> uid\n\
1965Return the current process's user id.";
1966
Barry Warsaw53699e91996-12-10 23:23:01 +00001967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001968posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001969{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001970 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001971 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001972 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001973}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001974#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001976
Guido van Rossumad0ee831995-03-01 10:34:45 +00001977#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001978static char posix_kill__doc__[] =
1979"kill(pid, sig) -> None\n\
1980Kill a process with a signal.";
1981
Barry Warsaw53699e91996-12-10 23:23:01 +00001982static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001983posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001984{
1985 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001986 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001987 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001988#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001989 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1990 APIRET rc;
1991 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001992 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001993
1994 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1995 APIRET rc;
1996 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001997 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001998
1999 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002000 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002001#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002002 if (kill(pid, sig) == -1)
2003 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002004#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002005 Py_INCREF(Py_None);
2006 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002007}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002008#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002009
Guido van Rossumc0125471996-06-28 18:55:32 +00002010#ifdef HAVE_PLOCK
2011
2012#ifdef HAVE_SYS_LOCK_H
2013#include <sys/lock.h>
2014#endif
2015
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002016static char posix_plock__doc__[] =
2017"plock(op) -> None\n\
2018Lock program segments into memory.";
2019
Barry Warsaw53699e91996-12-10 23:23:01 +00002020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002021posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002022{
2023 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002024 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002025 return NULL;
2026 if (plock(op) == -1)
2027 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002028 Py_INCREF(Py_None);
2029 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002030}
2031#endif
2032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002033
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002034#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002035static char posix_popen__doc__[] =
2036"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2037Open a pipe to/from a command returning a file object.";
2038
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002039#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002040static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002041async_system(const char *command)
2042{
2043 char *p, errormsg[256], args[1024];
2044 RESULTCODES rcodes;
2045 APIRET rc;
2046 char *shell = getenv("COMSPEC");
2047 if (!shell)
2048 shell = "cmd";
2049
2050 strcpy(args, shell);
2051 p = &args[ strlen(args)+1 ];
2052 strcpy(p, "/c ");
2053 strcat(p, command);
2054 p += strlen(p) + 1;
2055 *p = '\0';
2056
2057 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002058 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002059 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002060 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002061 &rcodes, shell);
2062 return rc;
2063}
2064
Guido van Rossumd48f2521997-12-05 22:19:34 +00002065static FILE *
2066popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002067{
2068 HFILE rhan, whan;
2069 FILE *retfd = NULL;
2070 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2071
Guido van Rossumd48f2521997-12-05 22:19:34 +00002072 if (rc != NO_ERROR) {
2073 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002074 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002075 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002076
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002077 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2078 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002079
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002080 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2081 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002082
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002083 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2084 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002085
2086 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002087 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002088 }
2089
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002090 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2091 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002092
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002093 close(oldfd); /* And Close Saved STDOUT Handle */
2094 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002095
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002096 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2097 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002098
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002099 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2100 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002101
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002102 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2103 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002104
2105 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002106 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002107 }
2108
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002109 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2110 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002111
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002112 close(oldfd); /* And Close Saved STDIN Handle */
2113 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002114
Guido van Rossumd48f2521997-12-05 22:19:34 +00002115 } else {
2116 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002117 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002118 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002119}
2120
2121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002122posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002123{
2124 char *name;
2125 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002126 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002127 FILE *fp;
2128 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002129 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002130 return NULL;
2131 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002132 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002133 Py_END_ALLOW_THREADS
2134 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002135 return os2_error(err);
2136
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002137 f = PyFile_FromFile(fp, name, mode, fclose);
2138 if (f != NULL)
2139 PyFile_SetBufSize(f, bufsize);
2140 return f;
2141}
2142
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002143#elif defined(MS_WIN32)
2144
2145/*
2146 * Portable 'popen' replacement for Win32.
2147 *
2148 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2149 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002150 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002151 */
2152
2153#include <malloc.h>
2154#include <io.h>
2155#include <fcntl.h>
2156
2157/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2158#define POPEN_1 1
2159#define POPEN_2 2
2160#define POPEN_3 3
2161#define POPEN_4 4
2162
2163static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002164static int _PyPclose(FILE *file);
2165
2166/*
2167 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002168 * for use when retrieving the process exit code. See _PyPclose() below
2169 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002170 */
2171static PyObject *_PyPopenProcs = NULL;
2172
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002173
2174/* popen that works from a GUI.
2175 *
2176 * The result of this function is a pipe (file) connected to the
2177 * processes stdin or stdout, depending on the requested mode.
2178 */
2179
2180static PyObject *
2181posix_popen(PyObject *self, PyObject *args)
2182{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002183 PyObject *f, *s;
2184 int tm = 0;
2185
2186 char *cmdstring;
2187 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002188 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002189 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002190 return NULL;
2191
2192 s = PyTuple_New(0);
2193
2194 if (*mode == 'r')
2195 tm = _O_RDONLY;
2196 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002197 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002198 return NULL;
2199 } else
2200 tm = _O_WRONLY;
2201
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002202 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002203 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002204 return NULL;
2205 }
2206
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002207 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002208 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002209 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002210 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002211 else
2212 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2213
2214 return f;
2215}
2216
2217/* Variation on win32pipe.popen
2218 *
2219 * The result of this function is a pipe (file) connected to the
2220 * process's stdin, and a pipe connected to the process's stdout.
2221 */
2222
2223static PyObject *
2224win32_popen2(PyObject *self, PyObject *args)
2225{
2226 PyObject *f;
2227 int tm=0;
2228
2229 char *cmdstring;
2230 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002231 int bufsize = -1;
2232 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002233 return NULL;
2234
2235 if (*mode == 't')
2236 tm = _O_TEXT;
2237 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002238 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002239 return NULL;
2240 } else
2241 tm = _O_BINARY;
2242
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002243 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002244 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002245 return NULL;
2246 }
2247
2248 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002249
2250 return f;
2251}
2252
2253/*
2254 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002255 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002256 * The result of this function is 3 pipes - the process's stdin,
2257 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002258 */
2259
2260static PyObject *
2261win32_popen3(PyObject *self, PyObject *args)
2262{
2263 PyObject *f;
2264 int tm = 0;
2265
2266 char *cmdstring;
2267 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002268 int bufsize = -1;
2269 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002270 return NULL;
2271
2272 if (*mode == 't')
2273 tm = _O_TEXT;
2274 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002275 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002276 return NULL;
2277 } else
2278 tm = _O_BINARY;
2279
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002280 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002281 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002282 return NULL;
2283 }
2284
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002285 f = _PyPopen(cmdstring, tm, POPEN_3);
2286
2287 return f;
2288}
2289
2290/*
2291 * Variation on win32pipe.popen
2292 *
2293 * The result of this function is 2 pipes - the processes stdin,
2294 * and stdout+stderr combined as a single pipe.
2295 */
2296
2297static PyObject *
2298win32_popen4(PyObject *self, PyObject *args)
2299{
2300 PyObject *f;
2301 int tm = 0;
2302
2303 char *cmdstring;
2304 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002305 int bufsize = -1;
2306 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002307 return NULL;
2308
2309 if (*mode == 't')
2310 tm = _O_TEXT;
2311 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002312 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002313 return NULL;
2314 } else
2315 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002316
2317 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002318 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002319 return NULL;
2320 }
2321
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002322 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002323
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002324 return f;
2325}
2326
Mark Hammond08501372001-01-31 07:30:29 +00002327static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002328_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002329 HANDLE hStdin,
2330 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002331 HANDLE hStderr,
2332 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002333{
2334 PROCESS_INFORMATION piProcInfo;
2335 STARTUPINFO siStartInfo;
2336 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002337 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002338 int i;
2339 int x;
2340
2341 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2342 s1 = (char *)_alloca(i);
2343 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2344 return x;
2345 if (GetVersion() < 0x80000000) {
2346 /*
2347 * NT/2000
2348 */
2349 x = i + strlen(s3) + strlen(cmdstring) + 1;
2350 s2 = (char *)_alloca(x);
2351 ZeroMemory(s2, x);
2352 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2353 }
2354 else {
2355 /*
2356 * Oh gag, we're on Win9x. Use the workaround listed in
2357 * KB: Q150956
2358 */
Mark Hammond08501372001-01-31 07:30:29 +00002359 char modulepath[_MAX_PATH];
2360 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002361 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2362 for (i = x = 0; modulepath[i]; i++)
2363 if (modulepath[i] == '\\')
2364 x = i+1;
2365 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002366 /* Create the full-name to w9xpopen, so we can test it exists */
2367 strncat(modulepath,
2368 szConsoleSpawn,
2369 (sizeof(modulepath)/sizeof(modulepath[0]))
2370 -strlen(modulepath));
2371 if (stat(modulepath, &statinfo) != 0) {
2372 /* Eeek - file-not-found - possibly an embedding
2373 situation - see if we can locate it in sys.prefix
2374 */
2375 strncpy(modulepath,
2376 Py_GetExecPrefix(),
2377 sizeof(modulepath)/sizeof(modulepath[0]));
2378 if (modulepath[strlen(modulepath)-1] != '\\')
2379 strcat(modulepath, "\\");
2380 strncat(modulepath,
2381 szConsoleSpawn,
2382 (sizeof(modulepath)/sizeof(modulepath[0]))
2383 -strlen(modulepath));
2384 /* No where else to look - raise an easily identifiable
2385 error, rather than leaving Windows to report
2386 "file not found" - as the user is probably blissfully
2387 unaware this shim EXE is used, and it will confuse them.
2388 (well, it confused me for a while ;-)
2389 */
2390 if (stat(modulepath, &statinfo) != 0) {
2391 PyErr_Format(PyExc_RuntimeError,
2392 "Can not locate '%s' which is needed "
2393 "for popen to work on this platform.",
2394 szConsoleSpawn);
2395 return FALSE;
2396 }
2397 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002398 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2399 strlen(modulepath) +
2400 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002401
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002402 s2 = (char *)_alloca(x);
2403 ZeroMemory(s2, x);
2404 sprintf(
2405 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002406 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002407 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002408 s1,
2409 s3,
2410 cmdstring);
2411 }
2412 }
2413
2414 /* Could be an else here to try cmd.exe / command.com in the path
2415 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002416 else {
2417 PyErr_SetString(PyExc_RuntimeError, "Can not locate a COMSPEC environment variable to use as the shell");
2418 return FALSE;
2419 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002420
2421 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2422 siStartInfo.cb = sizeof(STARTUPINFO);
2423 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2424 siStartInfo.hStdInput = hStdin;
2425 siStartInfo.hStdOutput = hStdout;
2426 siStartInfo.hStdError = hStderr;
2427 siStartInfo.wShowWindow = SW_HIDE;
2428
2429 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002430 s2,
2431 NULL,
2432 NULL,
2433 TRUE,
2434 CREATE_NEW_CONSOLE,
2435 NULL,
2436 NULL,
2437 &siStartInfo,
2438 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002439 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002440 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002441
Mark Hammondb37a3732000-08-14 04:47:33 +00002442 /* Return process handle */
2443 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002444 return TRUE;
2445 }
Mark Hammond08501372001-01-31 07:30:29 +00002446 win32_error("CreateProcess", NULL);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002447 return FALSE;
2448}
2449
2450/* The following code is based off of KB: Q190351 */
2451
2452static PyObject *
2453_PyPopen(char *cmdstring, int mode, int n)
2454{
2455 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2456 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002457 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002458
2459 SECURITY_ATTRIBUTES saAttr;
2460 BOOL fSuccess;
2461 int fd1, fd2, fd3;
2462 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002463 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002464 PyObject *f;
2465
2466 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2467 saAttr.bInheritHandle = TRUE;
2468 saAttr.lpSecurityDescriptor = NULL;
2469
2470 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2471 return win32_error("CreatePipe", NULL);
2472
2473 /* Create new output read handle and the input write handle. Set
2474 * the inheritance properties to FALSE. Otherwise, the child inherits
2475 * the these handles; resulting in non-closeable handles to the pipes
2476 * being created. */
2477 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002478 GetCurrentProcess(), &hChildStdinWrDup, 0,
2479 FALSE,
2480 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002481 if (!fSuccess)
2482 return win32_error("DuplicateHandle", NULL);
2483
2484 /* Close the inheritable version of ChildStdin
2485 that we're using. */
2486 CloseHandle(hChildStdinWr);
2487
2488 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2489 return win32_error("CreatePipe", NULL);
2490
2491 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002492 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2493 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002494 if (!fSuccess)
2495 return win32_error("DuplicateHandle", NULL);
2496
2497 /* Close the inheritable version of ChildStdout
2498 that we're using. */
2499 CloseHandle(hChildStdoutRd);
2500
2501 if (n != POPEN_4) {
2502 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2503 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002504 fSuccess = DuplicateHandle(GetCurrentProcess(),
2505 hChildStderrRd,
2506 GetCurrentProcess(),
2507 &hChildStderrRdDup, 0,
2508 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002509 if (!fSuccess)
2510 return win32_error("DuplicateHandle", NULL);
2511 /* Close the inheritable version of ChildStdErr that we're using. */
2512 CloseHandle(hChildStderrRd);
2513 }
2514
2515 switch (n) {
2516 case POPEN_1:
2517 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2518 case _O_WRONLY | _O_TEXT:
2519 /* Case for writing to child Stdin in text mode. */
2520 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2521 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002522 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002523 PyFile_SetBufSize(f, 0);
2524 /* We don't care about these pipes anymore, so close them. */
2525 CloseHandle(hChildStdoutRdDup);
2526 CloseHandle(hChildStderrRdDup);
2527 break;
2528
2529 case _O_RDONLY | _O_TEXT:
2530 /* Case for reading from child Stdout in text mode. */
2531 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2532 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002533 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002534 PyFile_SetBufSize(f, 0);
2535 /* We don't care about these pipes anymore, so close them. */
2536 CloseHandle(hChildStdinWrDup);
2537 CloseHandle(hChildStderrRdDup);
2538 break;
2539
2540 case _O_RDONLY | _O_BINARY:
2541 /* Case for readinig from child Stdout in binary mode. */
2542 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2543 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002544 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002545 PyFile_SetBufSize(f, 0);
2546 /* We don't care about these pipes anymore, so close them. */
2547 CloseHandle(hChildStdinWrDup);
2548 CloseHandle(hChildStderrRdDup);
2549 break;
2550
2551 case _O_WRONLY | _O_BINARY:
2552 /* Case for writing to child Stdin in binary mode. */
2553 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2554 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002555 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002556 PyFile_SetBufSize(f, 0);
2557 /* We don't care about these pipes anymore, so close them. */
2558 CloseHandle(hChildStdoutRdDup);
2559 CloseHandle(hChildStderrRdDup);
2560 break;
2561 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002562 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002563 break;
2564
2565 case POPEN_2:
2566 case POPEN_4:
2567 {
2568 char *m1, *m2;
2569 PyObject *p1, *p2;
2570
2571 if (mode && _O_TEXT) {
2572 m1 = "r";
2573 m2 = "w";
2574 } else {
2575 m1 = "rb";
2576 m2 = "wb";
2577 }
2578
2579 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2580 f1 = _fdopen(fd1, m2);
2581 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2582 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002583 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002584 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002585 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002586 PyFile_SetBufSize(p2, 0);
2587
2588 if (n != 4)
2589 CloseHandle(hChildStderrRdDup);
2590
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002591 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002592 Py_XDECREF(p1);
2593 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002594 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002595 break;
2596 }
2597
2598 case POPEN_3:
2599 {
2600 char *m1, *m2;
2601 PyObject *p1, *p2, *p3;
2602
2603 if (mode && _O_TEXT) {
2604 m1 = "r";
2605 m2 = "w";
2606 } else {
2607 m1 = "rb";
2608 m2 = "wb";
2609 }
2610
2611 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2612 f1 = _fdopen(fd1, m2);
2613 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2614 f2 = _fdopen(fd2, m1);
2615 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2616 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002617 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002618 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2619 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002620 PyFile_SetBufSize(p1, 0);
2621 PyFile_SetBufSize(p2, 0);
2622 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002623 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002624 Py_XDECREF(p1);
2625 Py_XDECREF(p2);
2626 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002627 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002628 break;
2629 }
2630 }
2631
2632 if (n == POPEN_4) {
2633 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002634 hChildStdinRd,
2635 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002636 hChildStdoutWr,
2637 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002638 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002639 }
2640 else {
2641 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002642 hChildStdinRd,
2643 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002644 hChildStderrWr,
2645 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002646 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002647 }
2648
Mark Hammondb37a3732000-08-14 04:47:33 +00002649 /*
2650 * Insert the files we've created into the process dictionary
2651 * all referencing the list with the process handle and the
2652 * initial number of files (see description below in _PyPclose).
2653 * Since if _PyPclose later tried to wait on a process when all
2654 * handles weren't closed, it could create a deadlock with the
2655 * child, we spend some energy here to try to ensure that we
2656 * either insert all file handles into the dictionary or none
2657 * at all. It's a little clumsy with the various popen modes
2658 * and variable number of files involved.
2659 */
2660 if (!_PyPopenProcs) {
2661 _PyPopenProcs = PyDict_New();
2662 }
2663
2664 if (_PyPopenProcs) {
2665 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2666 int ins_rc[3];
2667
2668 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2669 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2670
2671 procObj = PyList_New(2);
2672 hProcessObj = PyLong_FromVoidPtr(hProcess);
2673 intObj = PyInt_FromLong(file_count);
2674
2675 if (procObj && hProcessObj && intObj) {
2676 PyList_SetItem(procObj,0,hProcessObj);
2677 PyList_SetItem(procObj,1,intObj);
2678
2679 fileObj[0] = PyLong_FromVoidPtr(f1);
2680 if (fileObj[0]) {
2681 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2682 fileObj[0],
2683 procObj);
2684 }
2685 if (file_count >= 2) {
2686 fileObj[1] = PyLong_FromVoidPtr(f2);
2687 if (fileObj[1]) {
2688 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2689 fileObj[1],
2690 procObj);
2691 }
2692 }
2693 if (file_count >= 3) {
2694 fileObj[2] = PyLong_FromVoidPtr(f3);
2695 if (fileObj[2]) {
2696 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2697 fileObj[2],
2698 procObj);
2699 }
2700 }
2701
2702 if (ins_rc[0] < 0 || !fileObj[0] ||
2703 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2704 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2705 /* Something failed - remove any dictionary
2706 * entries that did make it.
2707 */
2708 if (!ins_rc[0] && fileObj[0]) {
2709 PyDict_DelItem(_PyPopenProcs,
2710 fileObj[0]);
2711 }
2712 if (!ins_rc[1] && fileObj[1]) {
2713 PyDict_DelItem(_PyPopenProcs,
2714 fileObj[1]);
2715 }
2716 if (!ins_rc[2] && fileObj[2]) {
2717 PyDict_DelItem(_PyPopenProcs,
2718 fileObj[2]);
2719 }
2720 }
2721 }
2722
2723 /*
2724 * Clean up our localized references for the dictionary keys
2725 * and value since PyDict_SetItem will Py_INCREF any copies
2726 * that got placed in the dictionary.
2727 */
2728 Py_XDECREF(procObj);
2729 Py_XDECREF(fileObj[0]);
2730 Py_XDECREF(fileObj[1]);
2731 Py_XDECREF(fileObj[2]);
2732 }
2733
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002734 /* Child is launched. Close the parents copy of those pipe
2735 * handles that only the child should have open. You need to
2736 * make sure that no handles to the write end of the output pipe
2737 * are maintained in this process or else the pipe will not close
2738 * when the child process exits and the ReadFile will hang. */
2739
2740 if (!CloseHandle(hChildStdinRd))
2741 return win32_error("CloseHandle", NULL);
2742
2743 if (!CloseHandle(hChildStdoutWr))
2744 return win32_error("CloseHandle", NULL);
2745
2746 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2747 return win32_error("CloseHandle", NULL);
2748
2749 return f;
2750}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002751
2752/*
2753 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2754 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002755 *
2756 * This function uses the _PyPopenProcs dictionary in order to map the
2757 * input file pointer to information about the process that was
2758 * originally created by the popen* call that created the file pointer.
2759 * The dictionary uses the file pointer as a key (with one entry
2760 * inserted for each file returned by the original popen* call) and a
2761 * single list object as the value for all files from a single call.
2762 * The list object contains the Win32 process handle at [0], and a file
2763 * count at [1], which is initialized to the total number of file
2764 * handles using that list.
2765 *
2766 * This function closes whichever handle it is passed, and decrements
2767 * the file count in the dictionary for the process handle pointed to
2768 * by this file. On the last close (when the file count reaches zero),
2769 * this function will wait for the child process and then return its
2770 * exit code as the result of the close() operation. This permits the
2771 * files to be closed in any order - it is always the close() of the
2772 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002773 */
Tim Peters736aa322000-09-01 06:51:24 +00002774
2775 /* RED_FLAG 31-Aug-2000 Tim
2776 * This is always called (today!) between a pair of
2777 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2778 * macros. So the thread running this has no valid thread state, as
2779 * far as Python is concerned. However, this calls some Python API
2780 * functions that cannot be called safely without a valid thread
2781 * state, in particular PyDict_GetItem.
2782 * As a temporary hack (although it may last for years ...), we
2783 * *rely* on not having a valid thread state in this function, in
2784 * order to create our own "from scratch".
2785 * This will deadlock if _PyPclose is ever called by a thread
2786 * holding the global lock.
2787 */
2788
Fredrik Lundh56055a42000-07-23 19:47:12 +00002789static int _PyPclose(FILE *file)
2790{
Fredrik Lundh20318932000-07-26 17:29:12 +00002791 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002792 DWORD exit_code;
2793 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002794 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2795 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002796#ifdef WITH_THREAD
2797 PyInterpreterState* pInterpreterState;
2798 PyThreadState* pThreadState;
2799#endif
2800
Fredrik Lundh20318932000-07-26 17:29:12 +00002801 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002802 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002803 */
2804 result = fclose(file);
2805
Tim Peters736aa322000-09-01 06:51:24 +00002806#ifdef WITH_THREAD
2807 /* Bootstrap a valid thread state into existence. */
2808 pInterpreterState = PyInterpreterState_New();
2809 if (!pInterpreterState) {
2810 /* Well, we're hosed now! We don't have a thread
2811 * state, so can't call a nice error routine, or raise
2812 * an exception. Just die.
2813 */
2814 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002815 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002816 return -1; /* unreachable */
2817 }
2818 pThreadState = PyThreadState_New(pInterpreterState);
2819 if (!pThreadState) {
2820 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002821 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002822 return -1; /* unreachable */
2823 }
2824 /* Grab the global lock. Note that this will deadlock if the
2825 * current thread already has the lock! (see RED_FLAG comments
2826 * before this function)
2827 */
2828 PyEval_RestoreThread(pThreadState);
2829#endif
2830
Fredrik Lundh56055a42000-07-23 19:47:12 +00002831 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002832 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2833 (procObj = PyDict_GetItem(_PyPopenProcs,
2834 fileObj)) != NULL &&
2835 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2836 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2837
2838 hProcess = PyLong_AsVoidPtr(hProcessObj);
2839 file_count = PyInt_AsLong(intObj);
2840
2841 if (file_count > 1) {
2842 /* Still other files referencing process */
2843 file_count--;
2844 PyList_SetItem(procObj,1,
2845 PyInt_FromLong(file_count));
2846 } else {
2847 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002848 if (result != EOF &&
2849 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2850 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002851 /* Possible truncation here in 16-bit environments, but
2852 * real exit codes are just the lower byte in any event.
2853 */
2854 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002855 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002856 /* Indicate failure - this will cause the file object
2857 * to raise an I/O error and translate the last Win32
2858 * error code from errno. We do have a problem with
2859 * last errors that overlap the normal errno table,
2860 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002861 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002862 if (result != EOF) {
2863 /* If the error wasn't from the fclose(), then
2864 * set errno for the file object error handling.
2865 */
2866 errno = GetLastError();
2867 }
2868 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002869 }
2870
2871 /* Free up the native handle at this point */
2872 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002873 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002874
Mark Hammondb37a3732000-08-14 04:47:33 +00002875 /* Remove this file pointer from dictionary */
2876 PyDict_DelItem(_PyPopenProcs, fileObj);
2877
2878 if (PyDict_Size(_PyPopenProcs) == 0) {
2879 Py_DECREF(_PyPopenProcs);
2880 _PyPopenProcs = NULL;
2881 }
2882
2883 } /* if object retrieval ok */
2884
2885 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002886 } /* if _PyPopenProcs */
2887
Tim Peters736aa322000-09-01 06:51:24 +00002888#ifdef WITH_THREAD
2889 /* Tear down the thread & interpreter states.
2890 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002891 * call the thread clear & delete functions, and indeed insist on
2892 * doing that themselves. The lock must be held during the clear, but
2893 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002894 */
2895 PyInterpreterState_Clear(pInterpreterState);
2896 PyEval_ReleaseThread(pThreadState);
2897 PyInterpreterState_Delete(pInterpreterState);
2898#endif
2899
Fredrik Lundh56055a42000-07-23 19:47:12 +00002900 return result;
2901}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002902
2903#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002904static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002905posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002906{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002907 char *name;
2908 char *mode = "r";
2909 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002910 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002911 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002912 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002913 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002914 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002915 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002916 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002917 if (fp == NULL)
2918 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002919 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002920 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002921 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002922 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002923}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002924#endif
2925
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002926#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002927
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002928
Guido van Rossumb6775db1994-08-01 11:34:53 +00002929#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002930static char posix_setuid__doc__[] =
2931"setuid(uid) -> None\n\
2932Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002933static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002934posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002935{
2936 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002937 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002938 return NULL;
2939 if (setuid(uid) < 0)
2940 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002941 Py_INCREF(Py_None);
2942 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002943}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002944#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002946
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002947#ifdef HAVE_SETEUID
2948static char posix_seteuid__doc__[] =
2949"seteuid(uid) -> None\n\
2950Set the current process's effective user id.";
2951static PyObject *
2952posix_seteuid (PyObject *self, PyObject *args)
2953{
2954 int euid;
2955 if (!PyArg_ParseTuple(args, "i", &euid)) {
2956 return NULL;
2957 } else if (seteuid(euid) < 0) {
2958 return posix_error();
2959 } else {
2960 Py_INCREF(Py_None);
2961 return Py_None;
2962 }
2963}
2964#endif /* HAVE_SETEUID */
2965
2966#ifdef HAVE_SETEGID
2967static char posix_setegid__doc__[] =
2968"setegid(gid) -> None\n\
2969Set the current process's effective group id.";
2970static PyObject *
2971posix_setegid (PyObject *self, PyObject *args)
2972{
2973 int egid;
2974 if (!PyArg_ParseTuple(args, "i", &egid)) {
2975 return NULL;
2976 } else if (setegid(egid) < 0) {
2977 return posix_error();
2978 } else {
2979 Py_INCREF(Py_None);
2980 return Py_None;
2981 }
2982}
2983#endif /* HAVE_SETEGID */
2984
2985#ifdef HAVE_SETREUID
2986static char posix_setreuid__doc__[] =
2987"seteuid(ruid, euid) -> None\n\
2988Set the current process's real and effective user ids.";
2989static PyObject *
2990posix_setreuid (PyObject *self, PyObject *args)
2991{
2992 int ruid, euid;
2993 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2994 return NULL;
2995 } else if (setreuid(ruid, euid) < 0) {
2996 return posix_error();
2997 } else {
2998 Py_INCREF(Py_None);
2999 return Py_None;
3000 }
3001}
3002#endif /* HAVE_SETREUID */
3003
3004#ifdef HAVE_SETREGID
3005static char posix_setregid__doc__[] =
3006"setegid(rgid, egid) -> None\n\
3007Set the current process's real and effective group ids.";
3008static PyObject *
3009posix_setregid (PyObject *self, PyObject *args)
3010{
3011 int rgid, egid;
3012 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3013 return NULL;
3014 } else if (setregid(rgid, egid) < 0) {
3015 return posix_error();
3016 } else {
3017 Py_INCREF(Py_None);
3018 return Py_None;
3019 }
3020}
3021#endif /* HAVE_SETREGID */
3022
Guido van Rossumb6775db1994-08-01 11:34:53 +00003023#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003024static char posix_setgid__doc__[] =
3025"setgid(gid) -> None\n\
3026Set the current process's group id.";
3027
Barry Warsaw53699e91996-12-10 23:23:01 +00003028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003029posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003030{
3031 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003032 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003033 return NULL;
3034 if (setgid(gid) < 0)
3035 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003036 Py_INCREF(Py_None);
3037 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003038}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003039#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003040
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003041
Guido van Rossumb6775db1994-08-01 11:34:53 +00003042#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003043static char posix_waitpid__doc__[] =
3044"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003045Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003046
Barry Warsaw53699e91996-12-10 23:23:01 +00003047static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003048posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003049{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003050 int pid, options;
3051#ifdef UNION_WAIT
3052 union wait status;
3053#define status_i (status.w_status)
3054#else
3055 int status;
3056#define status_i status
3057#endif
3058 status_i = 0;
3059
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003060 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003061 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003062 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003063#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003064 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003065#else
3066 pid = waitpid(pid, &status, options);
3067#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003068 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003069 if (pid == -1)
3070 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003071 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003072 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003073}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003074#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003076
Guido van Rossumad0ee831995-03-01 10:34:45 +00003077#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003078static char posix_wait__doc__[] =
3079"wait() -> (pid, status)\n\
3080Wait for completion of a child process.";
3081
Barry Warsaw53699e91996-12-10 23:23:01 +00003082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003083posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003084{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003085 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003086#ifdef UNION_WAIT
3087 union wait status;
3088#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003089#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003090 int status;
3091#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003092#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003093 if (!PyArg_ParseTuple(args, ":wait"))
3094 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003095 status_i = 0;
3096 Py_BEGIN_ALLOW_THREADS
3097 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003098 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003099 if (pid == -1)
3100 return posix_error();
3101 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003102 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003103#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003104}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003105#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003107
3108static char posix_lstat__doc__[] =
3109"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3110Like stat(path), but do not follow symbolic links.";
3111
Barry Warsaw53699e91996-12-10 23:23:01 +00003112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003113posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003114{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003115#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003116 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003117#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00003118 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003119#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003120}
3121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003122
Guido van Rossumb6775db1994-08-01 11:34:53 +00003123#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003124static char posix_readlink__doc__[] =
3125"readlink(path) -> path\n\
3126Return a string representing the path to which the symbolic link points.";
3127
Barry Warsaw53699e91996-12-10 23:23:01 +00003128static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003129posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003130{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003131 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003132 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003133 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003134 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003135 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003136 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003137 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003138 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003139 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003140 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003141 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003142}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003143#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003145
Guido van Rossumb6775db1994-08-01 11:34:53 +00003146#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003147static char posix_symlink__doc__[] =
3148"symlink(src, dst) -> None\n\
3149Create a symbolic link.";
3150
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003152posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003153{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003154 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003155}
3156#endif /* HAVE_SYMLINK */
3157
3158
3159#ifdef HAVE_TIMES
3160#ifndef HZ
3161#define HZ 60 /* Universal constant :-) */
3162#endif /* HZ */
3163
Guido van Rossumd48f2521997-12-05 22:19:34 +00003164#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3165static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003166system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003167{
3168 ULONG value = 0;
3169
3170 Py_BEGIN_ALLOW_THREADS
3171 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3172 Py_END_ALLOW_THREADS
3173
3174 return value;
3175}
3176
3177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003178posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003179{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003180 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003181 return NULL;
3182
3183 /* Currently Only Uptime is Provided -- Others Later */
3184 return Py_BuildValue("ddddd",
3185 (double)0 /* t.tms_utime / HZ */,
3186 (double)0 /* t.tms_stime / HZ */,
3187 (double)0 /* t.tms_cutime / HZ */,
3188 (double)0 /* t.tms_cstime / HZ */,
3189 (double)system_uptime() / 1000);
3190}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003191#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003193posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003194{
3195 struct tms t;
3196 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003197 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003198 return NULL;
3199 errno = 0;
3200 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003201 if (c == (clock_t) -1)
3202 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003203 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003204 (double)t.tms_utime / HZ,
3205 (double)t.tms_stime / HZ,
3206 (double)t.tms_cutime / HZ,
3207 (double)t.tms_cstime / HZ,
3208 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003209}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003210#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003211#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003212
3213
Guido van Rossum87755a21996-09-07 00:59:43 +00003214#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003215#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003217posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003218{
3219 FILETIME create, exit, kernel, user;
3220 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003221 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003222 return NULL;
3223 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003224 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3225 /* The fields of a FILETIME structure are the hi and lo part
3226 of a 64-bit value expressed in 100 nanosecond units.
3227 1e7 is one second in such units; 1e-7 the inverse.
3228 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3229 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003230 return Py_BuildValue(
3231 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003232 (double)(kernel.dwHighDateTime*429.4967296 +
3233 kernel.dwLowDateTime*1e-7),
3234 (double)(user.dwHighDateTime*429.4967296 +
3235 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003236 (double)0,
3237 (double)0,
3238 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003239}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003240#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003241
3242#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003243static char posix_times__doc__[] =
3244"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3245Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003246#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003247
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003248
Guido van Rossumb6775db1994-08-01 11:34:53 +00003249#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003250static char posix_setsid__doc__[] =
3251"setsid() -> None\n\
3252Call the system call setsid().";
3253
Barry Warsaw53699e91996-12-10 23:23:01 +00003254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003255posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003256{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003257 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003258 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003259 if (setsid() < 0)
3260 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003261 Py_INCREF(Py_None);
3262 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003263}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003264#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003265
Guido van Rossumb6775db1994-08-01 11:34:53 +00003266#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003267static char posix_setpgid__doc__[] =
3268"setpgid(pid, pgrp) -> None\n\
3269Call the system call setpgid().";
3270
Barry Warsaw53699e91996-12-10 23:23:01 +00003271static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003272posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003273{
3274 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003275 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003276 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003277 if (setpgid(pid, pgrp) < 0)
3278 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003279 Py_INCREF(Py_None);
3280 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003281}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003282#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003283
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284
Guido van Rossumb6775db1994-08-01 11:34:53 +00003285#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003286static char posix_tcgetpgrp__doc__[] =
3287"tcgetpgrp(fd) -> pgid\n\
3288Return the process group associated with the terminal given by a fd.";
3289
Barry Warsaw53699e91996-12-10 23:23:01 +00003290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003291posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003292{
3293 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003294 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003295 return NULL;
3296 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003297 if (pgid < 0)
3298 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003299 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003300}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003301#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003302
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003303
Guido van Rossumb6775db1994-08-01 11:34:53 +00003304#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003305static char posix_tcsetpgrp__doc__[] =
3306"tcsetpgrp(fd, pgid) -> None\n\
3307Set the process group associated with the terminal given by a fd.";
3308
Barry Warsaw53699e91996-12-10 23:23:01 +00003309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003310posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003311{
3312 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003313 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003314 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003315 if (tcsetpgrp(fd, pgid) < 0)
3316 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003317 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003318 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003319}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003320#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003321
Guido van Rossum687dd131993-05-17 08:34:16 +00003322/* Functions acting on file descriptors */
3323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003324static char posix_open__doc__[] =
3325"open(filename, flag [, mode=0777]) -> fd\n\
3326Open a file (for low level IO).";
3327
Barry Warsaw53699e91996-12-10 23:23:01 +00003328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003329posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003330{
3331 char *file;
3332 int flag;
3333 int mode = 0777;
3334 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003335 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3336 return NULL;
3337
Barry Warsaw53699e91996-12-10 23:23:01 +00003338 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003339 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003340 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003341 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003342 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003343 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003344}
3345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003346
3347static char posix_close__doc__[] =
3348"close(fd) -> None\n\
3349Close a file descriptor (for low level IO).";
3350
Barry Warsaw53699e91996-12-10 23:23:01 +00003351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003352posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003353{
3354 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003355 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003356 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003357 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003358 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003359 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003360 if (res < 0)
3361 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003362 Py_INCREF(Py_None);
3363 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003364}
3365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003366
3367static char posix_dup__doc__[] =
3368"dup(fd) -> fd2\n\
3369Return a duplicate of a file descriptor.";
3370
Barry Warsaw53699e91996-12-10 23:23:01 +00003371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003372posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003373{
3374 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003375 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003376 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003377 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003378 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003379 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003380 if (fd < 0)
3381 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003382 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003383}
3384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003385
3386static char posix_dup2__doc__[] =
3387"dup2(fd, fd2) -> None\n\
3388Duplicate file descriptor.";
3389
Barry Warsaw53699e91996-12-10 23:23:01 +00003390static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003391posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003392{
3393 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003394 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003395 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003396 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003397 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003398 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003399 if (res < 0)
3400 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003401 Py_INCREF(Py_None);
3402 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003403}
3404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003405
3406static char posix_lseek__doc__[] =
3407"lseek(fd, pos, how) -> newpos\n\
3408Set the current position of a file descriptor.";
3409
Barry Warsaw53699e91996-12-10 23:23:01 +00003410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003411posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003412{
3413 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003414#ifdef MS_WIN64
3415 LONG_LONG pos, res;
3416#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003417 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003418#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003419 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003420 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003421 return NULL;
3422#ifdef SEEK_SET
3423 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3424 switch (how) {
3425 case 0: how = SEEK_SET; break;
3426 case 1: how = SEEK_CUR; break;
3427 case 2: how = SEEK_END; break;
3428 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003429#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003430
3431#if !defined(HAVE_LARGEFILE_SUPPORT)
3432 pos = PyInt_AsLong(posobj);
3433#else
3434 pos = PyLong_Check(posobj) ?
3435 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3436#endif
3437 if (PyErr_Occurred())
3438 return NULL;
3439
Barry Warsaw53699e91996-12-10 23:23:01 +00003440 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003441#ifdef MS_WIN64
3442 res = _lseeki64(fd, pos, how);
3443#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003444 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003445#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003446 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003447 if (res < 0)
3448 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003449
3450#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003451 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003452#else
3453 return PyLong_FromLongLong(res);
3454#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003455}
3456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003457
3458static char posix_read__doc__[] =
3459"read(fd, buffersize) -> string\n\
3460Read a file descriptor.";
3461
Barry Warsaw53699e91996-12-10 23:23:01 +00003462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003463posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003464{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003465 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003466 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003467 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003468 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003469 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003470 if (buffer == NULL)
3471 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003472 Py_BEGIN_ALLOW_THREADS
3473 n = read(fd, PyString_AsString(buffer), size);
3474 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003475 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003476 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003477 return posix_error();
3478 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003479 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003480 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003481 return buffer;
3482}
3483
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003484
3485static char posix_write__doc__[] =
3486"write(fd, string) -> byteswritten\n\
3487Write a string to a file descriptor.";
3488
Barry Warsaw53699e91996-12-10 23:23:01 +00003489static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003490posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003491{
3492 int fd, size;
3493 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003494 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003495 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003496 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003497 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003498 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003499 if (size < 0)
3500 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003501 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003502}
3503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003504
3505static char posix_fstat__doc__[]=
3506"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3507Like stat(), but for an open file descriptor.";
3508
Barry Warsaw53699e91996-12-10 23:23:01 +00003509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003510posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003511{
3512 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003513 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003514 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003515 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003516 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003517 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003518 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003519 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003520 if (res != 0)
3521 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003522
3523 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003524}
3525
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003526
3527static char posix_fdopen__doc__[] =
3528"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3529Return an open file object connected to a file descriptor.";
3530
Barry Warsaw53699e91996-12-10 23:23:01 +00003531static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003532posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003533{
Guido van Rossum687dd131993-05-17 08:34:16 +00003534 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003535 char *mode = "r";
3536 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003537 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003538 PyObject *f;
3539 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003540 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003541
Barry Warsaw53699e91996-12-10 23:23:01 +00003542 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003543 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003544 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003545 if (fp == NULL)
3546 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003547 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003548 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003549 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003550 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003551}
3552
Skip Montanaro1517d842000-07-19 14:34:14 +00003553static char posix_isatty__doc__[] =
3554"isatty(fd) -> Boolean\n\
3555Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003556connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003557
3558static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003559posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003560{
3561 int fd;
3562 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3563 return NULL;
3564 return Py_BuildValue("i", isatty(fd));
3565}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003566
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003567#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003568static char posix_pipe__doc__[] =
3569"pipe() -> (read_end, write_end)\n\
3570Create a pipe.";
3571
Barry Warsaw53699e91996-12-10 23:23:01 +00003572static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003573posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003574{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003575#if defined(PYOS_OS2)
3576 HFILE read, write;
3577 APIRET rc;
3578
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003579 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003580 return NULL;
3581
3582 Py_BEGIN_ALLOW_THREADS
3583 rc = DosCreatePipe( &read, &write, 4096);
3584 Py_END_ALLOW_THREADS
3585 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003586 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003587
3588 return Py_BuildValue("(ii)", read, write);
3589#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003590#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003591 int fds[2];
3592 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003593 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003594 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003595 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003596 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003597 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003598 if (res != 0)
3599 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003600 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003601#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003602 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003603 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003604 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003605 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003606 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003607 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003608 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003609 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003610 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003611 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003612 read_fd = _open_osfhandle((intptr_t)read, 0);
3613 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003614 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003615#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003616#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003617}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003618#endif /* HAVE_PIPE */
3619
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003620
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003621#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003622static char posix_mkfifo__doc__[] =
3623"mkfifo(file, [, mode=0666]) -> None\n\
3624Create a FIFO (a POSIX named pipe).";
3625
Barry Warsaw53699e91996-12-10 23:23:01 +00003626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003627posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003628{
3629 char *file;
3630 int mode = 0666;
3631 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003632 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003633 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003634 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003635 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003636 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003637 if (res < 0)
3638 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003639 Py_INCREF(Py_None);
3640 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003641}
3642#endif
3643
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003644
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003645#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003646static char posix_ftruncate__doc__[] =
3647"ftruncate(fd, length) -> None\n\
3648Truncate a file to a specified length.";
3649
Barry Warsaw53699e91996-12-10 23:23:01 +00003650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003651posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003652{
3653 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003654 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003655 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003656 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003657
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003658 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003659 return NULL;
3660
3661#if !defined(HAVE_LARGEFILE_SUPPORT)
3662 length = PyInt_AsLong(lenobj);
3663#else
3664 length = PyLong_Check(lenobj) ?
3665 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3666#endif
3667 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003668 return NULL;
3669
Barry Warsaw53699e91996-12-10 23:23:01 +00003670 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003671 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003672 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003673 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003674 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003675 return NULL;
3676 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003677 Py_INCREF(Py_None);
3678 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003679}
3680#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003681
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003682#ifdef NeXT
3683#define HAVE_PUTENV
3684/* Steve Spicklemire got this putenv from NeXTAnswers */
3685static int
3686putenv(char *newval)
3687{
3688 extern char **environ;
3689
3690 static int firstTime = 1;
3691 char **ep;
3692 char *cp;
3693 int esiz;
3694 char *np;
3695
3696 if (!(np = strchr(newval, '=')))
3697 return 1;
3698 *np = '\0';
3699
3700 /* look it up */
3701 for (ep=environ ; *ep ; ep++)
3702 {
3703 /* this should always be true... */
3704 if (cp = strchr(*ep, '='))
3705 {
3706 *cp = '\0';
3707 if (!strcmp(*ep, newval))
3708 {
3709 /* got it! */
3710 *cp = '=';
3711 break;
3712 }
3713 *cp = '=';
3714 }
3715 else
3716 {
3717 *np = '=';
3718 return 1;
3719 }
3720 }
3721
3722 *np = '=';
3723 if (*ep)
3724 {
3725 /* the string was already there:
3726 just replace it with the new one */
3727 *ep = newval;
3728 return 0;
3729 }
3730
3731 /* expand environ by one */
3732 for (esiz=2, ep=environ ; *ep ; ep++)
3733 esiz++;
3734 if (firstTime)
3735 {
3736 char **epp;
3737 char **newenv;
3738 if (!(newenv = malloc(esiz * sizeof(char *))))
3739 return 1;
3740
3741 for (ep=environ, epp=newenv ; *ep ;)
3742 *epp++ = *ep++;
3743 *epp++ = newval;
3744 *epp = (char *) 0;
3745 environ = newenv;
3746 }
3747 else
3748 {
3749 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3750 return 1;
3751 environ[esiz - 2] = newval;
3752 environ[esiz - 1] = (char *) 0;
3753 firstTime = 0;
3754 }
3755
3756 return 0;
3757}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003758#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003760
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003761#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003762static char posix_putenv__doc__[] =
3763"putenv(key, value) -> None\n\
3764Change or add an environment variable.";
3765
Fred Drake762e2061999-08-26 17:23:54 +00003766/* Save putenv() parameters as values here, so we can collect them when they
3767 * get re-set with another call for the same key. */
3768static PyObject *posix_putenv_garbage;
3769
Barry Warsaw53699e91996-12-10 23:23:01 +00003770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003771posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003772{
3773 char *s1, *s2;
3774 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003775 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003776
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003777 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003778 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003779
3780#if defined(PYOS_OS2)
3781 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3782 APIRET rc;
3783
3784 if (strlen(s2) == 0) /* If New Value is an Empty String */
3785 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3786
3787 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3788 if (rc != NO_ERROR)
3789 return os2_error(rc);
3790
3791 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3792 APIRET rc;
3793
3794 if (strlen(s2) == 0) /* If New Value is an Empty String */
3795 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3796
3797 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3798 if (rc != NO_ERROR)
3799 return os2_error(rc);
3800 } else {
3801#endif
3802
Fred Drake762e2061999-08-26 17:23:54 +00003803 /* XXX This can leak memory -- not easy to fix :-( */
3804 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3805 if (newstr == NULL)
3806 return PyErr_NoMemory();
3807 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003808 (void) sprintf(new, "%s=%s", s1, s2);
3809 if (putenv(new)) {
3810 posix_error();
3811 return NULL;
3812 }
Fred Drake762e2061999-08-26 17:23:54 +00003813 /* Install the first arg and newstr in posix_putenv_garbage;
3814 * this will cause previous value to be collected. This has to
3815 * happen after the real putenv() call because the old value
3816 * was still accessible until then. */
3817 if (PyDict_SetItem(posix_putenv_garbage,
3818 PyTuple_GET_ITEM(args, 0), newstr)) {
3819 /* really not much we can do; just leak */
3820 PyErr_Clear();
3821 }
3822 else {
3823 Py_DECREF(newstr);
3824 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003825
3826#if defined(PYOS_OS2)
3827 }
3828#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003829 Py_INCREF(Py_None);
3830 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003831}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003832#endif /* putenv */
3833
3834#ifdef HAVE_STRERROR
3835static char posix_strerror__doc__[] =
3836"strerror(code) -> string\n\
3837Translate an error code to a message string.";
3838
3839PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003840posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003841{
3842 int code;
3843 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003844 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003845 return NULL;
3846 message = strerror(code);
3847 if (message == NULL) {
3848 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003849 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003850 return NULL;
3851 }
3852 return PyString_FromString(message);
3853}
3854#endif /* strerror */
3855
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003856
Guido van Rossumc9641791998-08-04 15:26:23 +00003857#ifdef HAVE_SYS_WAIT_H
3858
3859#ifdef WIFSTOPPED
3860static char posix_WIFSTOPPED__doc__[] =
3861"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003862Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003863
3864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003865posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003866{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003867#ifdef UNION_WAIT
3868 union wait status;
3869#define status_i (status.w_status)
3870#else
3871 int status;
3872#define status_i status
3873#endif
3874 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003875
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003876 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003877 {
3878 return NULL;
3879 }
3880
3881 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003882#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003883}
3884#endif /* WIFSTOPPED */
3885
3886#ifdef WIFSIGNALED
3887static char posix_WIFSIGNALED__doc__[] =
3888"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003889Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003890
3891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003892posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003893{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003894#ifdef UNION_WAIT
3895 union wait status;
3896#define status_i (status.w_status)
3897#else
3898 int status;
3899#define status_i status
3900#endif
3901 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003902
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003903 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003904 {
3905 return NULL;
3906 }
3907
3908 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003909#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003910}
3911#endif /* WIFSIGNALED */
3912
3913#ifdef WIFEXITED
3914static char posix_WIFEXITED__doc__[] =
3915"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003916Return true if the process returning 'status' exited using the exit()\n\
3917system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003918
3919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003920posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003921{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003922#ifdef UNION_WAIT
3923 union wait status;
3924#define status_i (status.w_status)
3925#else
3926 int status;
3927#define status_i status
3928#endif
3929 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003930
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003931 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003932 {
3933 return NULL;
3934 }
3935
3936 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003937#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003938}
3939#endif /* WIFEXITED */
3940
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003941#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003942static char posix_WEXITSTATUS__doc__[] =
3943"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003944Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003945
3946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003947posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003948{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003949#ifdef UNION_WAIT
3950 union wait status;
3951#define status_i (status.w_status)
3952#else
3953 int status;
3954#define status_i status
3955#endif
3956 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003957
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003958 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003959 {
3960 return NULL;
3961 }
3962
3963 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003964#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003965}
3966#endif /* WEXITSTATUS */
3967
3968#ifdef WTERMSIG
3969static char posix_WTERMSIG__doc__[] =
3970"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003971Return the signal that terminated the process that provided the 'status'\n\
3972value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003973
3974static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003975posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003976{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003977#ifdef UNION_WAIT
3978 union wait status;
3979#define status_i (status.w_status)
3980#else
3981 int status;
3982#define status_i status
3983#endif
3984 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003985
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003986 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003987 {
3988 return NULL;
3989 }
3990
3991 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003992#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003993}
3994#endif /* WTERMSIG */
3995
3996#ifdef WSTOPSIG
3997static char posix_WSTOPSIG__doc__[] =
3998"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003999Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004000
4001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004002posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004003{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004004#ifdef UNION_WAIT
4005 union wait status;
4006#define status_i (status.w_status)
4007#else
4008 int status;
4009#define status_i status
4010#endif
4011 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004012
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004013 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004014 {
4015 return NULL;
4016 }
4017
4018 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004019#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004020}
4021#endif /* WSTOPSIG */
4022
4023#endif /* HAVE_SYS_WAIT_H */
4024
4025
Guido van Rossum94f6f721999-01-06 18:42:14 +00004026#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004027#ifdef _SCO_DS
4028/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4029 needed definitions in sys/statvfs.h */
4030#define _SVID3
4031#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004032#include <sys/statvfs.h>
4033
4034static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004035"fstatvfs(fd) -> \n\
4036 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004037Perform an fstatvfs system call on the given fd.";
4038
4039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004040posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004041{
4042 int fd, res;
4043 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004044 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004045 return NULL;
4046 Py_BEGIN_ALLOW_THREADS
4047 res = fstatvfs(fd, &st);
4048 Py_END_ALLOW_THREADS
4049 if (res != 0)
4050 return posix_error();
4051#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004052 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004053 (long) st.f_bsize,
4054 (long) st.f_frsize,
4055 (long) st.f_blocks,
4056 (long) st.f_bfree,
4057 (long) st.f_bavail,
4058 (long) st.f_files,
4059 (long) st.f_ffree,
4060 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004061 (long) st.f_flag,
4062 (long) st.f_namemax);
4063#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004064 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004065 (long) st.f_bsize,
4066 (long) st.f_frsize,
4067 (LONG_LONG) st.f_blocks,
4068 (LONG_LONG) st.f_bfree,
4069 (LONG_LONG) st.f_bavail,
4070 (LONG_LONG) st.f_files,
4071 (LONG_LONG) st.f_ffree,
4072 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004073 (long) st.f_flag,
4074 (long) st.f_namemax);
4075#endif
4076}
4077#endif /* HAVE_FSTATVFS */
4078
4079
4080#if defined(HAVE_STATVFS)
4081#include <sys/statvfs.h>
4082
4083static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004084"statvfs(path) -> \n\
4085 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004086Perform a statvfs system call on the given path.";
4087
4088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004089posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004090{
4091 char *path;
4092 int res;
4093 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004094 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004095 return NULL;
4096 Py_BEGIN_ALLOW_THREADS
4097 res = statvfs(path, &st);
4098 Py_END_ALLOW_THREADS
4099 if (res != 0)
4100 return posix_error_with_filename(path);
4101#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004102 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004103 (long) st.f_bsize,
4104 (long) st.f_frsize,
4105 (long) st.f_blocks,
4106 (long) st.f_bfree,
4107 (long) st.f_bavail,
4108 (long) st.f_files,
4109 (long) st.f_ffree,
4110 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004111 (long) st.f_flag,
4112 (long) st.f_namemax);
4113#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004114 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004115 (long) st.f_bsize,
4116 (long) st.f_frsize,
4117 (LONG_LONG) st.f_blocks,
4118 (LONG_LONG) st.f_bfree,
4119 (LONG_LONG) st.f_bavail,
4120 (LONG_LONG) st.f_files,
4121 (LONG_LONG) st.f_ffree,
4122 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004123 (long) st.f_flag,
4124 (long) st.f_namemax);
4125#endif
4126}
4127#endif /* HAVE_STATVFS */
4128
4129
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004130#ifdef HAVE_TEMPNAM
4131static char posix_tempnam__doc__[] = "\
4132tempnam([dir[, prefix]]) -> string\n\
4133Return a unique name for a temporary file.\n\
4134The directory and a short may be specified as strings; they may be omitted\n\
4135or None if not needed.";
4136
4137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004138posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004139{
4140 PyObject *result = NULL;
4141 char *dir = NULL;
4142 char *pfx = NULL;
4143 char *name;
4144
4145 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4146 return NULL;
4147 name = tempnam(dir, pfx);
4148 if (name == NULL)
4149 return PyErr_NoMemory();
4150 result = PyString_FromString(name);
4151 free(name);
4152 return result;
4153}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004154#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004155
4156
4157#ifdef HAVE_TMPFILE
4158static char posix_tmpfile__doc__[] = "\
4159tmpfile() -> file object\n\
4160Create a temporary file with no directory entries.";
4161
4162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004163posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004164{
4165 FILE *fp;
4166
4167 if (!PyArg_ParseTuple(args, ":tmpfile"))
4168 return NULL;
4169 fp = tmpfile();
4170 if (fp == NULL)
4171 return posix_error();
4172 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4173}
4174#endif
4175
4176
4177#ifdef HAVE_TMPNAM
4178static char posix_tmpnam__doc__[] = "\
4179tmpnam() -> string\n\
4180Return a unique name for a temporary file.";
4181
4182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004183posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004184{
4185 char buffer[L_tmpnam];
4186 char *name;
4187
4188 if (!PyArg_ParseTuple(args, ":tmpnam"))
4189 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004190#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004191 name = tmpnam_r(buffer);
4192#else
4193 name = tmpnam(buffer);
4194#endif
4195 if (name == NULL) {
4196 PyErr_SetObject(PyExc_OSError,
4197 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004198#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004199 "unexpected NULL from tmpnam_r"
4200#else
4201 "unexpected NULL from tmpnam"
4202#endif
4203 ));
4204 return NULL;
4205 }
4206 return PyString_FromString(buffer);
4207}
4208#endif
4209
4210
Fred Drakec9680921999-12-13 16:37:25 +00004211/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4212 * It maps strings representing configuration variable names to
4213 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004214 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004215 * rarely-used constants. There are three separate tables that use
4216 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004217 *
4218 * This code is always included, even if none of the interfaces that
4219 * need it are included. The #if hackery needed to avoid it would be
4220 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004221 */
4222struct constdef {
4223 char *name;
4224 long value;
4225};
4226
Fred Drake12c6e2d1999-12-14 21:25:03 +00004227static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004228conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4229 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004230{
4231 if (PyInt_Check(arg)) {
4232 *valuep = PyInt_AS_LONG(arg);
4233 return 1;
4234 }
4235 if (PyString_Check(arg)) {
4236 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004237 size_t lo = 0;
4238 size_t mid;
4239 size_t hi = tablesize;
4240 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004241 char *confname = PyString_AS_STRING(arg);
4242 while (lo < hi) {
4243 mid = (lo + hi) / 2;
4244 cmp = strcmp(confname, table[mid].name);
4245 if (cmp < 0)
4246 hi = mid;
4247 else if (cmp > 0)
4248 lo = mid + 1;
4249 else {
4250 *valuep = table[mid].value;
4251 return 1;
4252 }
4253 }
4254 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4255 }
4256 else
4257 PyErr_SetString(PyExc_TypeError,
4258 "configuration names must be strings or integers");
4259 return 0;
4260}
4261
4262
4263#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4264static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004265#ifdef _PC_ABI_AIO_XFER_MAX
4266 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4267#endif
4268#ifdef _PC_ABI_ASYNC_IO
4269 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4270#endif
Fred Drakec9680921999-12-13 16:37:25 +00004271#ifdef _PC_ASYNC_IO
4272 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4273#endif
4274#ifdef _PC_CHOWN_RESTRICTED
4275 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4276#endif
4277#ifdef _PC_FILESIZEBITS
4278 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4279#endif
4280#ifdef _PC_LAST
4281 {"PC_LAST", _PC_LAST},
4282#endif
4283#ifdef _PC_LINK_MAX
4284 {"PC_LINK_MAX", _PC_LINK_MAX},
4285#endif
4286#ifdef _PC_MAX_CANON
4287 {"PC_MAX_CANON", _PC_MAX_CANON},
4288#endif
4289#ifdef _PC_MAX_INPUT
4290 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4291#endif
4292#ifdef _PC_NAME_MAX
4293 {"PC_NAME_MAX", _PC_NAME_MAX},
4294#endif
4295#ifdef _PC_NO_TRUNC
4296 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4297#endif
4298#ifdef _PC_PATH_MAX
4299 {"PC_PATH_MAX", _PC_PATH_MAX},
4300#endif
4301#ifdef _PC_PIPE_BUF
4302 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4303#endif
4304#ifdef _PC_PRIO_IO
4305 {"PC_PRIO_IO", _PC_PRIO_IO},
4306#endif
4307#ifdef _PC_SOCK_MAXBUF
4308 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4309#endif
4310#ifdef _PC_SYNC_IO
4311 {"PC_SYNC_IO", _PC_SYNC_IO},
4312#endif
4313#ifdef _PC_VDISABLE
4314 {"PC_VDISABLE", _PC_VDISABLE},
4315#endif
4316};
4317
Fred Drakec9680921999-12-13 16:37:25 +00004318static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004319conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004320{
4321 return conv_confname(arg, valuep, posix_constants_pathconf,
4322 sizeof(posix_constants_pathconf)
4323 / sizeof(struct constdef));
4324}
4325#endif
4326
4327#ifdef HAVE_FPATHCONF
4328static char posix_fpathconf__doc__[] = "\
4329fpathconf(fd, name) -> integer\n\
4330Return the configuration limit name for the file descriptor fd.\n\
4331If there is no limit, return -1.";
4332
4333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004334posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004335{
4336 PyObject *result = NULL;
4337 int name, fd;
4338
Fred Drake12c6e2d1999-12-14 21:25:03 +00004339 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4340 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004341 long limit;
4342
4343 errno = 0;
4344 limit = fpathconf(fd, name);
4345 if (limit == -1 && errno != 0)
4346 posix_error();
4347 else
4348 result = PyInt_FromLong(limit);
4349 }
4350 return result;
4351}
4352#endif
4353
4354
4355#ifdef HAVE_PATHCONF
4356static char posix_pathconf__doc__[] = "\
4357pathconf(path, name) -> integer\n\
4358Return the configuration limit name for the file or directory path.\n\
4359If there is no limit, return -1.";
4360
4361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004362posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004363{
4364 PyObject *result = NULL;
4365 int name;
4366 char *path;
4367
4368 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4369 conv_path_confname, &name)) {
4370 long limit;
4371
4372 errno = 0;
4373 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004374 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004375 if (errno == EINVAL)
4376 /* could be a path or name problem */
4377 posix_error();
4378 else
4379 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004380 }
Fred Drakec9680921999-12-13 16:37:25 +00004381 else
4382 result = PyInt_FromLong(limit);
4383 }
4384 return result;
4385}
4386#endif
4387
4388#ifdef HAVE_CONFSTR
4389static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004390#ifdef _CS_ARCHITECTURE
4391 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4392#endif
4393#ifdef _CS_HOSTNAME
4394 {"CS_HOSTNAME", _CS_HOSTNAME},
4395#endif
4396#ifdef _CS_HW_PROVIDER
4397 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4398#endif
4399#ifdef _CS_HW_SERIAL
4400 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4401#endif
4402#ifdef _CS_INITTAB_NAME
4403 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4404#endif
Fred Drakec9680921999-12-13 16:37:25 +00004405#ifdef _CS_LFS64_CFLAGS
4406 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4407#endif
4408#ifdef _CS_LFS64_LDFLAGS
4409 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4410#endif
4411#ifdef _CS_LFS64_LIBS
4412 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4413#endif
4414#ifdef _CS_LFS64_LINTFLAGS
4415 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4416#endif
4417#ifdef _CS_LFS_CFLAGS
4418 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4419#endif
4420#ifdef _CS_LFS_LDFLAGS
4421 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4422#endif
4423#ifdef _CS_LFS_LIBS
4424 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4425#endif
4426#ifdef _CS_LFS_LINTFLAGS
4427 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4428#endif
Fred Draked86ed291999-12-15 15:34:33 +00004429#ifdef _CS_MACHINE
4430 {"CS_MACHINE", _CS_MACHINE},
4431#endif
Fred Drakec9680921999-12-13 16:37:25 +00004432#ifdef _CS_PATH
4433 {"CS_PATH", _CS_PATH},
4434#endif
Fred Draked86ed291999-12-15 15:34:33 +00004435#ifdef _CS_RELEASE
4436 {"CS_RELEASE", _CS_RELEASE},
4437#endif
4438#ifdef _CS_SRPC_DOMAIN
4439 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4440#endif
4441#ifdef _CS_SYSNAME
4442 {"CS_SYSNAME", _CS_SYSNAME},
4443#endif
4444#ifdef _CS_VERSION
4445 {"CS_VERSION", _CS_VERSION},
4446#endif
Fred Drakec9680921999-12-13 16:37:25 +00004447#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4448 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4449#endif
4450#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4451 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4452#endif
4453#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4454 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4455#endif
4456#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4457 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4458#endif
4459#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4460 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4461#endif
4462#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4463 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4464#endif
4465#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4466 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4467#endif
4468#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4469 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4470#endif
4471#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4472 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4473#endif
4474#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4475 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4476#endif
4477#ifdef _CS_XBS5_LP64_OFF64_LIBS
4478 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4479#endif
4480#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4481 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4482#endif
4483#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4484 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4485#endif
4486#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4487 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4488#endif
4489#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4490 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4491#endif
4492#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4493 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4494#endif
Fred Draked86ed291999-12-15 15:34:33 +00004495#ifdef _MIPS_CS_AVAIL_PROCESSORS
4496 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4497#endif
4498#ifdef _MIPS_CS_BASE
4499 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4500#endif
4501#ifdef _MIPS_CS_HOSTID
4502 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4503#endif
4504#ifdef _MIPS_CS_HW_NAME
4505 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4506#endif
4507#ifdef _MIPS_CS_NUM_PROCESSORS
4508 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4509#endif
4510#ifdef _MIPS_CS_OSREL_MAJ
4511 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4512#endif
4513#ifdef _MIPS_CS_OSREL_MIN
4514 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4515#endif
4516#ifdef _MIPS_CS_OSREL_PATCH
4517 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4518#endif
4519#ifdef _MIPS_CS_OS_NAME
4520 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4521#endif
4522#ifdef _MIPS_CS_OS_PROVIDER
4523 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4524#endif
4525#ifdef _MIPS_CS_PROCESSORS
4526 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4527#endif
4528#ifdef _MIPS_CS_SERIAL
4529 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4530#endif
4531#ifdef _MIPS_CS_VENDOR
4532 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4533#endif
Fred Drakec9680921999-12-13 16:37:25 +00004534};
4535
4536static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004537conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004538{
4539 return conv_confname(arg, valuep, posix_constants_confstr,
4540 sizeof(posix_constants_confstr)
4541 / sizeof(struct constdef));
4542}
4543
4544static char posix_confstr__doc__[] = "\
4545confstr(name) -> string\n\
4546Return a string-valued system configuration variable.";
4547
4548static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004549posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004550{
4551 PyObject *result = NULL;
4552 int name;
4553 char buffer[64];
4554
4555 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4556 int len = confstr(name, buffer, sizeof(buffer));
4557
Fred Drakec9680921999-12-13 16:37:25 +00004558 errno = 0;
4559 if (len == 0) {
4560 if (errno != 0)
4561 posix_error();
4562 else
4563 result = PyString_FromString("");
4564 }
4565 else {
4566 if (len >= sizeof(buffer)) {
4567 result = PyString_FromStringAndSize(NULL, len);
4568 if (result != NULL)
4569 confstr(name, PyString_AS_STRING(result), len+1);
4570 }
4571 else
4572 result = PyString_FromString(buffer);
4573 }
4574 }
4575 return result;
4576}
4577#endif
4578
4579
4580#ifdef HAVE_SYSCONF
4581static struct constdef posix_constants_sysconf[] = {
4582#ifdef _SC_2_CHAR_TERM
4583 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4584#endif
4585#ifdef _SC_2_C_BIND
4586 {"SC_2_C_BIND", _SC_2_C_BIND},
4587#endif
4588#ifdef _SC_2_C_DEV
4589 {"SC_2_C_DEV", _SC_2_C_DEV},
4590#endif
4591#ifdef _SC_2_C_VERSION
4592 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4593#endif
4594#ifdef _SC_2_FORT_DEV
4595 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4596#endif
4597#ifdef _SC_2_FORT_RUN
4598 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4599#endif
4600#ifdef _SC_2_LOCALEDEF
4601 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4602#endif
4603#ifdef _SC_2_SW_DEV
4604 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4605#endif
4606#ifdef _SC_2_UPE
4607 {"SC_2_UPE", _SC_2_UPE},
4608#endif
4609#ifdef _SC_2_VERSION
4610 {"SC_2_VERSION", _SC_2_VERSION},
4611#endif
Fred Draked86ed291999-12-15 15:34:33 +00004612#ifdef _SC_ABI_ASYNCHRONOUS_IO
4613 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4614#endif
4615#ifdef _SC_ACL
4616 {"SC_ACL", _SC_ACL},
4617#endif
Fred Drakec9680921999-12-13 16:37:25 +00004618#ifdef _SC_AIO_LISTIO_MAX
4619 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4620#endif
Fred Drakec9680921999-12-13 16:37:25 +00004621#ifdef _SC_AIO_MAX
4622 {"SC_AIO_MAX", _SC_AIO_MAX},
4623#endif
4624#ifdef _SC_AIO_PRIO_DELTA_MAX
4625 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4626#endif
4627#ifdef _SC_ARG_MAX
4628 {"SC_ARG_MAX", _SC_ARG_MAX},
4629#endif
4630#ifdef _SC_ASYNCHRONOUS_IO
4631 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4632#endif
4633#ifdef _SC_ATEXIT_MAX
4634 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4635#endif
Fred Draked86ed291999-12-15 15:34:33 +00004636#ifdef _SC_AUDIT
4637 {"SC_AUDIT", _SC_AUDIT},
4638#endif
Fred Drakec9680921999-12-13 16:37:25 +00004639#ifdef _SC_AVPHYS_PAGES
4640 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4641#endif
4642#ifdef _SC_BC_BASE_MAX
4643 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4644#endif
4645#ifdef _SC_BC_DIM_MAX
4646 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4647#endif
4648#ifdef _SC_BC_SCALE_MAX
4649 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4650#endif
4651#ifdef _SC_BC_STRING_MAX
4652 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4653#endif
Fred Draked86ed291999-12-15 15:34:33 +00004654#ifdef _SC_CAP
4655 {"SC_CAP", _SC_CAP},
4656#endif
Fred Drakec9680921999-12-13 16:37:25 +00004657#ifdef _SC_CHARCLASS_NAME_MAX
4658 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4659#endif
4660#ifdef _SC_CHAR_BIT
4661 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4662#endif
4663#ifdef _SC_CHAR_MAX
4664 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4665#endif
4666#ifdef _SC_CHAR_MIN
4667 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4668#endif
4669#ifdef _SC_CHILD_MAX
4670 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4671#endif
4672#ifdef _SC_CLK_TCK
4673 {"SC_CLK_TCK", _SC_CLK_TCK},
4674#endif
4675#ifdef _SC_COHER_BLKSZ
4676 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4677#endif
4678#ifdef _SC_COLL_WEIGHTS_MAX
4679 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4680#endif
4681#ifdef _SC_DCACHE_ASSOC
4682 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4683#endif
4684#ifdef _SC_DCACHE_BLKSZ
4685 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4686#endif
4687#ifdef _SC_DCACHE_LINESZ
4688 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4689#endif
4690#ifdef _SC_DCACHE_SZ
4691 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4692#endif
4693#ifdef _SC_DCACHE_TBLKSZ
4694 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4695#endif
4696#ifdef _SC_DELAYTIMER_MAX
4697 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4698#endif
4699#ifdef _SC_EQUIV_CLASS_MAX
4700 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4701#endif
4702#ifdef _SC_EXPR_NEST_MAX
4703 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4704#endif
4705#ifdef _SC_FSYNC
4706 {"SC_FSYNC", _SC_FSYNC},
4707#endif
4708#ifdef _SC_GETGR_R_SIZE_MAX
4709 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4710#endif
4711#ifdef _SC_GETPW_R_SIZE_MAX
4712 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4713#endif
4714#ifdef _SC_ICACHE_ASSOC
4715 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4716#endif
4717#ifdef _SC_ICACHE_BLKSZ
4718 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4719#endif
4720#ifdef _SC_ICACHE_LINESZ
4721 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4722#endif
4723#ifdef _SC_ICACHE_SZ
4724 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4725#endif
Fred Draked86ed291999-12-15 15:34:33 +00004726#ifdef _SC_INF
4727 {"SC_INF", _SC_INF},
4728#endif
Fred Drakec9680921999-12-13 16:37:25 +00004729#ifdef _SC_INT_MAX
4730 {"SC_INT_MAX", _SC_INT_MAX},
4731#endif
4732#ifdef _SC_INT_MIN
4733 {"SC_INT_MIN", _SC_INT_MIN},
4734#endif
4735#ifdef _SC_IOV_MAX
4736 {"SC_IOV_MAX", _SC_IOV_MAX},
4737#endif
Fred Draked86ed291999-12-15 15:34:33 +00004738#ifdef _SC_IP_SECOPTS
4739 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4740#endif
Fred Drakec9680921999-12-13 16:37:25 +00004741#ifdef _SC_JOB_CONTROL
4742 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4743#endif
Fred Draked86ed291999-12-15 15:34:33 +00004744#ifdef _SC_KERN_POINTERS
4745 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4746#endif
4747#ifdef _SC_KERN_SIM
4748 {"SC_KERN_SIM", _SC_KERN_SIM},
4749#endif
Fred Drakec9680921999-12-13 16:37:25 +00004750#ifdef _SC_LINE_MAX
4751 {"SC_LINE_MAX", _SC_LINE_MAX},
4752#endif
4753#ifdef _SC_LOGIN_NAME_MAX
4754 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4755#endif
4756#ifdef _SC_LOGNAME_MAX
4757 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4758#endif
4759#ifdef _SC_LONG_BIT
4760 {"SC_LONG_BIT", _SC_LONG_BIT},
4761#endif
Fred Draked86ed291999-12-15 15:34:33 +00004762#ifdef _SC_MAC
4763 {"SC_MAC", _SC_MAC},
4764#endif
Fred Drakec9680921999-12-13 16:37:25 +00004765#ifdef _SC_MAPPED_FILES
4766 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4767#endif
4768#ifdef _SC_MAXPID
4769 {"SC_MAXPID", _SC_MAXPID},
4770#endif
4771#ifdef _SC_MB_LEN_MAX
4772 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4773#endif
4774#ifdef _SC_MEMLOCK
4775 {"SC_MEMLOCK", _SC_MEMLOCK},
4776#endif
4777#ifdef _SC_MEMLOCK_RANGE
4778 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4779#endif
4780#ifdef _SC_MEMORY_PROTECTION
4781 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4782#endif
4783#ifdef _SC_MESSAGE_PASSING
4784 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4785#endif
Fred Draked86ed291999-12-15 15:34:33 +00004786#ifdef _SC_MMAP_FIXED_ALIGNMENT
4787 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4788#endif
Fred Drakec9680921999-12-13 16:37:25 +00004789#ifdef _SC_MQ_OPEN_MAX
4790 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4791#endif
4792#ifdef _SC_MQ_PRIO_MAX
4793 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4794#endif
Fred Draked86ed291999-12-15 15:34:33 +00004795#ifdef _SC_NACLS_MAX
4796 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4797#endif
Fred Drakec9680921999-12-13 16:37:25 +00004798#ifdef _SC_NGROUPS_MAX
4799 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4800#endif
4801#ifdef _SC_NL_ARGMAX
4802 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4803#endif
4804#ifdef _SC_NL_LANGMAX
4805 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4806#endif
4807#ifdef _SC_NL_MSGMAX
4808 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4809#endif
4810#ifdef _SC_NL_NMAX
4811 {"SC_NL_NMAX", _SC_NL_NMAX},
4812#endif
4813#ifdef _SC_NL_SETMAX
4814 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4815#endif
4816#ifdef _SC_NL_TEXTMAX
4817 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4818#endif
4819#ifdef _SC_NPROCESSORS_CONF
4820 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4821#endif
4822#ifdef _SC_NPROCESSORS_ONLN
4823 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4824#endif
Fred Draked86ed291999-12-15 15:34:33 +00004825#ifdef _SC_NPROC_CONF
4826 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4827#endif
4828#ifdef _SC_NPROC_ONLN
4829 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4830#endif
Fred Drakec9680921999-12-13 16:37:25 +00004831#ifdef _SC_NZERO
4832 {"SC_NZERO", _SC_NZERO},
4833#endif
4834#ifdef _SC_OPEN_MAX
4835 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4836#endif
4837#ifdef _SC_PAGESIZE
4838 {"SC_PAGESIZE", _SC_PAGESIZE},
4839#endif
4840#ifdef _SC_PAGE_SIZE
4841 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4842#endif
4843#ifdef _SC_PASS_MAX
4844 {"SC_PASS_MAX", _SC_PASS_MAX},
4845#endif
4846#ifdef _SC_PHYS_PAGES
4847 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4848#endif
4849#ifdef _SC_PII
4850 {"SC_PII", _SC_PII},
4851#endif
4852#ifdef _SC_PII_INTERNET
4853 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4854#endif
4855#ifdef _SC_PII_INTERNET_DGRAM
4856 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4857#endif
4858#ifdef _SC_PII_INTERNET_STREAM
4859 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4860#endif
4861#ifdef _SC_PII_OSI
4862 {"SC_PII_OSI", _SC_PII_OSI},
4863#endif
4864#ifdef _SC_PII_OSI_CLTS
4865 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4866#endif
4867#ifdef _SC_PII_OSI_COTS
4868 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4869#endif
4870#ifdef _SC_PII_OSI_M
4871 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4872#endif
4873#ifdef _SC_PII_SOCKET
4874 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4875#endif
4876#ifdef _SC_PII_XTI
4877 {"SC_PII_XTI", _SC_PII_XTI},
4878#endif
4879#ifdef _SC_POLL
4880 {"SC_POLL", _SC_POLL},
4881#endif
4882#ifdef _SC_PRIORITIZED_IO
4883 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4884#endif
4885#ifdef _SC_PRIORITY_SCHEDULING
4886 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4887#endif
4888#ifdef _SC_REALTIME_SIGNALS
4889 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4890#endif
4891#ifdef _SC_RE_DUP_MAX
4892 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4893#endif
4894#ifdef _SC_RTSIG_MAX
4895 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4896#endif
4897#ifdef _SC_SAVED_IDS
4898 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4899#endif
4900#ifdef _SC_SCHAR_MAX
4901 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4902#endif
4903#ifdef _SC_SCHAR_MIN
4904 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4905#endif
4906#ifdef _SC_SELECT
4907 {"SC_SELECT", _SC_SELECT},
4908#endif
4909#ifdef _SC_SEMAPHORES
4910 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4911#endif
4912#ifdef _SC_SEM_NSEMS_MAX
4913 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4914#endif
4915#ifdef _SC_SEM_VALUE_MAX
4916 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4917#endif
4918#ifdef _SC_SHARED_MEMORY_OBJECTS
4919 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4920#endif
4921#ifdef _SC_SHRT_MAX
4922 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4923#endif
4924#ifdef _SC_SHRT_MIN
4925 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4926#endif
4927#ifdef _SC_SIGQUEUE_MAX
4928 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4929#endif
4930#ifdef _SC_SIGRT_MAX
4931 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4932#endif
4933#ifdef _SC_SIGRT_MIN
4934 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4935#endif
Fred Draked86ed291999-12-15 15:34:33 +00004936#ifdef _SC_SOFTPOWER
4937 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4938#endif
Fred Drakec9680921999-12-13 16:37:25 +00004939#ifdef _SC_SPLIT_CACHE
4940 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4941#endif
4942#ifdef _SC_SSIZE_MAX
4943 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4944#endif
4945#ifdef _SC_STACK_PROT
4946 {"SC_STACK_PROT", _SC_STACK_PROT},
4947#endif
4948#ifdef _SC_STREAM_MAX
4949 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4950#endif
4951#ifdef _SC_SYNCHRONIZED_IO
4952 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4953#endif
4954#ifdef _SC_THREADS
4955 {"SC_THREADS", _SC_THREADS},
4956#endif
4957#ifdef _SC_THREAD_ATTR_STACKADDR
4958 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4959#endif
4960#ifdef _SC_THREAD_ATTR_STACKSIZE
4961 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4962#endif
4963#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4964 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4965#endif
4966#ifdef _SC_THREAD_KEYS_MAX
4967 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4968#endif
4969#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4970 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4971#endif
4972#ifdef _SC_THREAD_PRIO_INHERIT
4973 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4974#endif
4975#ifdef _SC_THREAD_PRIO_PROTECT
4976 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4977#endif
4978#ifdef _SC_THREAD_PROCESS_SHARED
4979 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4980#endif
4981#ifdef _SC_THREAD_SAFE_FUNCTIONS
4982 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4983#endif
4984#ifdef _SC_THREAD_STACK_MIN
4985 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4986#endif
4987#ifdef _SC_THREAD_THREADS_MAX
4988 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4989#endif
4990#ifdef _SC_TIMERS
4991 {"SC_TIMERS", _SC_TIMERS},
4992#endif
4993#ifdef _SC_TIMER_MAX
4994 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4995#endif
4996#ifdef _SC_TTY_NAME_MAX
4997 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4998#endif
4999#ifdef _SC_TZNAME_MAX
5000 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5001#endif
5002#ifdef _SC_T_IOV_MAX
5003 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5004#endif
5005#ifdef _SC_UCHAR_MAX
5006 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5007#endif
5008#ifdef _SC_UINT_MAX
5009 {"SC_UINT_MAX", _SC_UINT_MAX},
5010#endif
5011#ifdef _SC_UIO_MAXIOV
5012 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5013#endif
5014#ifdef _SC_ULONG_MAX
5015 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5016#endif
5017#ifdef _SC_USHRT_MAX
5018 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5019#endif
5020#ifdef _SC_VERSION
5021 {"SC_VERSION", _SC_VERSION},
5022#endif
5023#ifdef _SC_WORD_BIT
5024 {"SC_WORD_BIT", _SC_WORD_BIT},
5025#endif
5026#ifdef _SC_XBS5_ILP32_OFF32
5027 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5028#endif
5029#ifdef _SC_XBS5_ILP32_OFFBIG
5030 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5031#endif
5032#ifdef _SC_XBS5_LP64_OFF64
5033 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5034#endif
5035#ifdef _SC_XBS5_LPBIG_OFFBIG
5036 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5037#endif
5038#ifdef _SC_XOPEN_CRYPT
5039 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5040#endif
5041#ifdef _SC_XOPEN_ENH_I18N
5042 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5043#endif
5044#ifdef _SC_XOPEN_LEGACY
5045 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5046#endif
5047#ifdef _SC_XOPEN_REALTIME
5048 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5049#endif
5050#ifdef _SC_XOPEN_REALTIME_THREADS
5051 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5052#endif
5053#ifdef _SC_XOPEN_SHM
5054 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5055#endif
5056#ifdef _SC_XOPEN_UNIX
5057 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5058#endif
5059#ifdef _SC_XOPEN_VERSION
5060 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5061#endif
5062#ifdef _SC_XOPEN_XCU_VERSION
5063 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5064#endif
5065#ifdef _SC_XOPEN_XPG2
5066 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5067#endif
5068#ifdef _SC_XOPEN_XPG3
5069 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5070#endif
5071#ifdef _SC_XOPEN_XPG4
5072 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5073#endif
5074};
5075
5076static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005077conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005078{
5079 return conv_confname(arg, valuep, posix_constants_sysconf,
5080 sizeof(posix_constants_sysconf)
5081 / sizeof(struct constdef));
5082}
5083
5084static char posix_sysconf__doc__[] = "\
5085sysconf(name) -> integer\n\
5086Return an integer-valued system configuration variable.";
5087
5088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005089posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005090{
5091 PyObject *result = NULL;
5092 int name;
5093
5094 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5095 int value;
5096
5097 errno = 0;
5098 value = sysconf(name);
5099 if (value == -1 && errno != 0)
5100 posix_error();
5101 else
5102 result = PyInt_FromLong(value);
5103 }
5104 return result;
5105}
5106#endif
5107
5108
Fred Drakebec628d1999-12-15 18:31:10 +00005109/* This code is used to ensure that the tables of configuration value names
5110 * are in sorted order as required by conv_confname(), and also to build the
5111 * the exported dictionaries that are used to publish information about the
5112 * names available on the host platform.
5113 *
5114 * Sorting the table at runtime ensures that the table is properly ordered
5115 * when used, even for platforms we're not able to test on. It also makes
5116 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005117 */
Fred Drakebec628d1999-12-15 18:31:10 +00005118
5119static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005120cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005121{
5122 const struct constdef *c1 =
5123 (const struct constdef *) v1;
5124 const struct constdef *c2 =
5125 (const struct constdef *) v2;
5126
5127 return strcmp(c1->name, c2->name);
5128}
5129
5130static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005131setup_confname_table(struct constdef *table, size_t tablesize,
5132 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005133{
Fred Drakebec628d1999-12-15 18:31:10 +00005134 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005135 size_t i;
5136 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005137
5138 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5139 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005140 if (d == NULL)
5141 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005142
Barry Warsaw3155db32000-04-13 15:20:40 +00005143 for (i=0; i < tablesize; ++i) {
5144 PyObject *o = PyInt_FromLong(table[i].value);
5145 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5146 Py_XDECREF(o);
5147 Py_DECREF(d);
5148 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005149 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005150 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005151 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005152 status = PyDict_SetItemString(moddict, tablename, d);
5153 Py_DECREF(d);
5154 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005155}
5156
Fred Drakebec628d1999-12-15 18:31:10 +00005157/* Return -1 on failure, 0 on success. */
5158static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005159setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005160{
5161#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005162 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005163 sizeof(posix_constants_pathconf)
5164 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005165 "pathconf_names", moddict))
5166 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005167#endif
5168#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005169 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005170 sizeof(posix_constants_confstr)
5171 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005172 "confstr_names", moddict))
5173 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005174#endif
5175#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005176 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005177 sizeof(posix_constants_sysconf)
5178 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005179 "sysconf_names", moddict))
5180 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005181#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005182 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005183}
Fred Draked86ed291999-12-15 15:34:33 +00005184
5185
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005186static char posix_abort__doc__[] = "\
5187abort() -> does not return!\n\
5188Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5189in the hardest way possible on the hosting operating system.";
5190
5191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005192posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005193{
5194 if (!PyArg_ParseTuple(args, ":abort"))
5195 return NULL;
5196 abort();
5197 /*NOTREACHED*/
5198 Py_FatalError("abort() called from Python code didn't abort!");
5199 return NULL;
5200}
Fred Drakebec628d1999-12-15 18:31:10 +00005201
Tim Petersf58a7aa2000-09-22 10:05:54 +00005202#ifdef MS_WIN32
5203static char win32_startfile__doc__[] = "\
5204startfile(filepath) - Start a file with its associated application.\n\
5205\n\
5206This acts like double-clicking the file in Explorer, or giving the file\n\
5207name as an argument to the DOS \"start\" command: the file is opened\n\
5208with whatever application (if any) its extension is associated.\n\
5209\n\
5210startfile returns as soon as the associated application is launched.\n\
5211There is no option to wait for the application to close, and no way\n\
5212to retrieve the application's exit status.\n\
5213\n\
5214The filepath is relative to the current directory. If you want to use\n\
5215an absolute path, make sure the first character is not a slash (\"/\");\n\
5216the underlying Win32 ShellExecute function doesn't work if it is.";
5217
5218static PyObject *
5219win32_startfile(PyObject *self, PyObject *args)
5220{
5221 char *filepath;
5222 HINSTANCE rc;
5223 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5224 return NULL;
5225 Py_BEGIN_ALLOW_THREADS
5226 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5227 Py_END_ALLOW_THREADS
5228 if (rc <= (HINSTANCE)32)
5229 return win32_error("startfile", filepath);
5230 Py_INCREF(Py_None);
5231 return Py_None;
5232}
5233#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005234
5235static PyMethodDef posix_methods[] = {
5236 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5237#ifdef HAVE_TTYNAME
5238 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5239#endif
5240 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5241 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005242#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005243 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005244#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005245#ifdef HAVE_CTERMID
5246 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5247#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005248#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005249 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005250#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005251#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005252 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005253#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005254 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5255 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5256 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005257#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005258 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005259#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005260#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005261 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005262#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005263 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5264 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5265 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005266#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005267 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005268#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005269#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005270 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005271#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005272 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005273#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005274 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005275#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005276 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5277 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5278 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005279#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005280 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005281#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005282 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005283#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005284 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5285 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005286#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005287#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005288 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5289 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005290#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005291#ifdef HAVE_FORK1
5292 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5293#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005294#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005295 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005296#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005297#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005298 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005299#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005300#ifdef HAVE_FORKPTY
5301 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5302#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005303#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005304 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005305#endif /* HAVE_GETEGID */
5306#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005307 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005308#endif /* HAVE_GETEUID */
5309#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005310 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005311#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005312#ifdef HAVE_GETGROUPS
5313 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5314#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005315 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005316#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005317 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005318#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005319#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005320 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005321#endif /* HAVE_GETPPID */
5322#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005323 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005324#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005325#ifdef HAVE_GETLOGIN
5326 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5327#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005328#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005329 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005330#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005331#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005332 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005333#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005334#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005335 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005336#ifdef MS_WIN32
5337 {"popen2", win32_popen2, METH_VARARGS},
5338 {"popen3", win32_popen3, METH_VARARGS},
5339 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005340 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005341#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005342#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005343#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005344 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005345#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005346#ifdef HAVE_SETEUID
5347 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5348#endif /* HAVE_SETEUID */
5349#ifdef HAVE_SETEGID
5350 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5351#endif /* HAVE_SETEGID */
5352#ifdef HAVE_SETREUID
5353 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5354#endif /* HAVE_SETREUID */
5355#ifdef HAVE_SETREGID
5356 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5357#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005358#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005359 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005360#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005361#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005362 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005363#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005364#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005365 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005366#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005367#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005368 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005369#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005370#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005371 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005372#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005373#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005374 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005375#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005376#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005377 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005378#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005379#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005380 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005381#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005382 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5383 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5384 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5385 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5386 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5387 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5388 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5389 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5390 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005391 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005392#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005393 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005394#endif
5395#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005396 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005397#endif
5398#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005399 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005400#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005401#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005402 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005403#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005404#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005405 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005406#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005407#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005408 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005409#endif
5410#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005411 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005412#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005413#ifdef HAVE_SYS_WAIT_H
5414#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005415 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005416#endif /* WIFSTOPPED */
5417#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005418 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005419#endif /* WIFSIGNALED */
5420#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005421 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005422#endif /* WIFEXITED */
5423#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005424 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005425#endif /* WEXITSTATUS */
5426#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005427 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005428#endif /* WTERMSIG */
5429#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005430 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005431#endif /* WSTOPSIG */
5432#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005433#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005434 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005435#endif
5436#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005437 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005438#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005439#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005440 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5441#endif
5442#ifdef HAVE_TEMPNAM
5443 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5444#endif
5445#ifdef HAVE_TMPNAM
5446 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5447#endif
Fred Drakec9680921999-12-13 16:37:25 +00005448#ifdef HAVE_CONFSTR
5449 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5450#endif
5451#ifdef HAVE_SYSCONF
5452 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5453#endif
5454#ifdef HAVE_FPATHCONF
5455 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5456#endif
5457#ifdef HAVE_PATHCONF
5458 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5459#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005460 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005461 {NULL, NULL} /* Sentinel */
5462};
5463
5464
Barry Warsaw4a342091996-12-19 23:50:02 +00005465static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005466ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005467{
5468 PyObject* v = PyInt_FromLong(value);
5469 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5470 return -1; /* triggers fatal error */
5471
5472 Py_DECREF(v);
5473 return 0;
5474}
5475
Guido van Rossumd48f2521997-12-05 22:19:34 +00005476#if defined(PYOS_OS2)
5477/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5478static int insertvalues(PyObject *d)
5479{
5480 APIRET rc;
5481 ULONG values[QSV_MAX+1];
5482 PyObject *v;
5483 char *ver, tmp[10];
5484
5485 Py_BEGIN_ALLOW_THREADS
5486 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5487 Py_END_ALLOW_THREADS
5488
5489 if (rc != NO_ERROR) {
5490 os2_error(rc);
5491 return -1;
5492 }
5493
5494 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5495 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5496 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5497 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5498 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5499 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5500 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5501
5502 switch (values[QSV_VERSION_MINOR]) {
5503 case 0: ver = "2.00"; break;
5504 case 10: ver = "2.10"; break;
5505 case 11: ver = "2.11"; break;
5506 case 30: ver = "3.00"; break;
5507 case 40: ver = "4.00"; break;
5508 case 50: ver = "5.00"; break;
5509 default:
5510 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5511 values[QSV_VERSION_MINOR]);
5512 ver = &tmp[0];
5513 }
5514
5515 /* Add Indicator of the Version of the Operating System */
5516 v = PyString_FromString(ver);
5517 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5518 return -1;
5519 Py_DECREF(v);
5520
5521 /* Add Indicator of Which Drive was Used to Boot the System */
5522 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5523 tmp[1] = ':';
5524 tmp[2] = '\0';
5525
5526 v = PyString_FromString(tmp);
5527 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5528 return -1;
5529 Py_DECREF(v);
5530
5531 return 0;
5532}
5533#endif
5534
Barry Warsaw4a342091996-12-19 23:50:02 +00005535static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005536all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005537{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005538#ifdef F_OK
5539 if (ins(d, "F_OK", (long)F_OK)) return -1;
5540#endif
5541#ifdef R_OK
5542 if (ins(d, "R_OK", (long)R_OK)) return -1;
5543#endif
5544#ifdef W_OK
5545 if (ins(d, "W_OK", (long)W_OK)) return -1;
5546#endif
5547#ifdef X_OK
5548 if (ins(d, "X_OK", (long)X_OK)) return -1;
5549#endif
Fred Drakec9680921999-12-13 16:37:25 +00005550#ifdef NGROUPS_MAX
5551 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5552#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005553#ifdef TMP_MAX
5554 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5555#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005556#ifdef WNOHANG
5557 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5558#endif
5559#ifdef O_RDONLY
5560 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5561#endif
5562#ifdef O_WRONLY
5563 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5564#endif
5565#ifdef O_RDWR
5566 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5567#endif
5568#ifdef O_NDELAY
5569 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5570#endif
5571#ifdef O_NONBLOCK
5572 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5573#endif
5574#ifdef O_APPEND
5575 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5576#endif
5577#ifdef O_DSYNC
5578 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5579#endif
5580#ifdef O_RSYNC
5581 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5582#endif
5583#ifdef O_SYNC
5584 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5585#endif
5586#ifdef O_NOCTTY
5587 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5588#endif
5589#ifdef O_CREAT
5590 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5591#endif
5592#ifdef O_EXCL
5593 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5594#endif
5595#ifdef O_TRUNC
5596 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5597#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005598#ifdef O_BINARY
5599 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5600#endif
5601#ifdef O_TEXT
5602 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5603#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005604
Guido van Rossum246bc171999-02-01 23:54:31 +00005605#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005606 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5607 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5608 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5609 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5610 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005611#endif
5612
Guido van Rossumd48f2521997-12-05 22:19:34 +00005613#if defined(PYOS_OS2)
5614 if (insertvalues(d)) return -1;
5615#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005616 return 0;
5617}
5618
5619
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005620#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005621#define INITFUNC initnt
5622#define MODNAME "nt"
5623#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005624#if defined(PYOS_OS2)
5625#define INITFUNC initos2
5626#define MODNAME "os2"
5627#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005628#define INITFUNC initposix
5629#define MODNAME "posix"
5630#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005631#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005632
Guido van Rossum3886bb61998-12-04 18:50:17 +00005633DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005634INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005635{
Barry Warsaw53699e91996-12-10 23:23:01 +00005636 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005637
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005638 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005639 posix_methods,
5640 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005641 (PyObject *)NULL,
5642 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005643 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005644
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005645 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005646 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005647 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005648 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005649 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005650
Barry Warsaw4a342091996-12-19 23:50:02 +00005651 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005652 return;
5653
Fred Drakebec628d1999-12-15 18:31:10 +00005654 if (setup_confname_tables(d))
5655 return;
5656
Barry Warsawca74da41999-02-09 19:31:45 +00005657 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005658
Guido van Rossumb3d39562000-01-31 18:41:26 +00005659#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005660 if (posix_putenv_garbage == NULL)
5661 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005662#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005663}