blob: 8350e06e6d88f747cf56ecaa1847767a2029c7ce [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +000043/* Various compilers have only certain posix functions */
Guido van Rossum6d8841c1997-08-14 19:57:39 +000044/* XXX Gosh I wish these were all moved into config.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000046#include <process.h>
47#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000048#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000049#define HAVE_GETCWD 1
50#define HAVE_OPENDIR 1
51#define HAVE_SYSTEM 1
52#if defined(__OS2__)
53#define HAVE_EXECV 1
54#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000055#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000056#include <process.h>
57#else
58#ifdef __BORLANDC__ /* Borland compiler */
59#define HAVE_EXECV 1
60#define HAVE_GETCWD 1
61#define HAVE_GETEGID 1
62#define HAVE_GETEUID 1
63#define HAVE_GETGID 1
64#define HAVE_GETPPID 1
65#define HAVE_GETUID 1
66#define HAVE_KILL 1
67#define HAVE_OPENDIR 1
68#define HAVE_PIPE 1
69#define HAVE_POPEN 1
70#define HAVE_SYSTEM 1
71#define HAVE_WAIT 1
72#else
73#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000074#define HAVE_GETCWD 1
75#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000076#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#define HAVE_EXECV 1
78#define HAVE_PIPE 1
79#define HAVE_POPEN 1
80#define HAVE_SYSTEM 1
81#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000082#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000083#else /* all other compilers */
84/* Unix functions that the configure script doesn't check for */
85#define HAVE_EXECV 1
86#define HAVE_FORK 1
87#define HAVE_GETCWD 1
88#define HAVE_GETEGID 1
89#define HAVE_GETEUID 1
90#define HAVE_GETGID 1
91#define HAVE_GETPPID 1
92#define HAVE_GETUID 1
93#define HAVE_KILL 1
94#define HAVE_OPENDIR 1
95#define HAVE_PIPE 1
96#define HAVE_POPEN 1
97#define HAVE_SYSTEM 1
98#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +000099#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000100#endif /* _MSC_VER */
101#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000102#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000103#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000104
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000106
Guido van Rossumb6775db1994-08-01 11:34:53 +0000107#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000108#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000109#endif
110
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000111#if defined(sun) && !defined(__SVR4)
112/* SunOS 4.1.4 doesn't have prototypes for these: */
113extern int rename(const char *, const char *);
114extern int pclose(FILE *);
115extern int fclose(FILE *);
116#endif
117
Guido van Rossum36bc6801995-06-14 22:54:23 +0000118#ifdef NeXT
119/* NeXT's <unistd.h> and <utime.h> aren't worth much */
120#undef HAVE_UNISTD_H
121#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000122#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000123/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000124#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000125#endif
126
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000127#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000128#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000129extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000131#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000132extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000133#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000136#endif
137#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000138extern int chdir(char *);
139extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000140#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000141extern int chdir(const char *);
142extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000143#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000144extern int chmod(const char *, mode_t);
145extern int chown(const char *, uid_t, gid_t);
146extern char *getcwd(char *, int);
147extern char *strerror(int);
148extern int link(const char *, const char *);
149extern int rename(const char *, const char *);
150extern int stat(const char *, struct stat *);
151extern int unlink(const char *);
152extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000153#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000155#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000156#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000158#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000159#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000160
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000161#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162
Guido van Rossumb6775db1994-08-01 11:34:53 +0000163#ifdef HAVE_UTIME_H
164#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000165#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000166
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000167#ifdef HAVE_SYS_UTIME_H
168#include <sys/utime.h>
169#define HAVE_UTIME_H /* pretend we do for the rest of this file */
170#endif /* HAVE_SYS_UTIME_H */
171
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172#ifdef HAVE_SYS_TIMES_H
173#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000174#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175
176#ifdef HAVE_SYS_PARAM_H
177#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000178#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179
180#ifdef HAVE_SYS_UTSNAME_H
181#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000182#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183
184#ifndef MAXPATHLEN
185#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000186#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000188#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000190#define NAMLEN(dirent) strlen((dirent)->d_name)
191#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000192#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000193#include <direct.h>
194#define NAMLEN(dirent) strlen((dirent)->d_name)
195#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000197#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#endif
202#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#endif
205#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000206#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000207#endif
208#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <direct.h>
212#include <io.h>
213#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000214#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000216#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000218#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000219#else /* 16-bit Windows */
220#include <dos.h>
221#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000222#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
Guido van Rossumd48f2521997-12-05 22:19:34 +0000225#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000228
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000229#ifdef UNION_WAIT
230/* Emulate some macros on systems that have a union instead of macros */
231
232#ifndef WIFEXITED
233#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
234#endif
235
236#ifndef WEXITSTATUS
237#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
238#endif
239
240#ifndef WTERMSIG
241#define WTERMSIG(u_wait) ((u_wait).w_termsig)
242#endif
243
244#endif /* UNION_WAIT */
245
Greg Wardb48bc172000-03-01 21:51:56 +0000246/* Don't use the "_r" form if we don't need it (also, won't have a
247 prototype for it, at least on Solaris -- maybe others as well?). */
248#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
249#define USE_CTERMID_R
250#endif
251
252#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
253#define USE_TMPNAM_R
254#endif
255
Fred Drake699f3522000-06-29 21:12:41 +0000256/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000257#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000258#ifdef MS_WIN64
259# define STAT _stati64
260# define FSTAT _fstati64
261# define STRUCT_STAT struct _stati64
262#else
263# define STAT stat
264# define FSTAT fstat
265# define STRUCT_STAT struct stat
266#endif
267
268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269/* Return a dictionary corresponding to the POSIX environment table */
270
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000271#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000273#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274
Barry Warsaw53699e91996-12-10 23:23:01 +0000275static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000276convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277{
Barry Warsaw53699e91996-12-10 23:23:01 +0000278 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000280 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281 if (d == NULL)
282 return NULL;
283 if (environ == NULL)
284 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000285 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000287 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000288 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 char *p = strchr(*e, '=');
290 if (p == NULL)
291 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000292 k = PyString_FromStringAndSize(*e, (int)(p-*e));
293 if (k == NULL) {
294 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000296 }
297 v = PyString_FromString(p+1);
298 if (v == NULL) {
299 PyErr_Clear();
300 Py_DECREF(k);
301 continue;
302 }
303 if (PyDict_GetItem(d, k) == NULL) {
304 if (PyDict_SetItem(d, k, v) != 0)
305 PyErr_Clear();
306 }
307 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000308 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000310#if defined(PYOS_OS2)
311 {
312 APIRET rc;
313 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
314
315 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000316 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000317 PyObject *v = PyString_FromString(buffer);
318 PyDict_SetItemString(d, "BEGINLIBPATH", v);
319 Py_DECREF(v);
320 }
321 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
322 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
323 PyObject *v = PyString_FromString(buffer);
324 PyDict_SetItemString(d, "ENDLIBPATH", v);
325 Py_DECREF(v);
326 }
327 }
328#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 return d;
330}
331
332
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333/* Set a POSIX-specific error from errno, and return NULL */
334
Barry Warsawd58d7641998-07-23 16:14:40 +0000335static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000336posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000337{
Barry Warsawca74da41999-02-09 19:31:45 +0000338 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000339}
Barry Warsawd58d7641998-07-23 16:14:40 +0000340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000341posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000342{
Barry Warsawca74da41999-02-09 19:31:45 +0000343 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000344}
345
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000346#ifdef MS_WIN32
347static PyObject *
348win32_error(char* function, char* filename)
349{
Mark Hammond33a6da92000-08-15 00:46:38 +0000350 /* XXX We should pass the function name along in the future.
351 (_winreg.c also wants to pass the function name.)
352 This would however require an additional param to the
353 Windows error object, which is non-trivial.
354 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000355 errno = GetLastError();
356 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000357 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000358 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000359 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000360}
361#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000362
Guido van Rossumd48f2521997-12-05 22:19:34 +0000363#if defined(PYOS_OS2)
364/**********************************************************************
365 * Helper Function to Trim and Format OS/2 Messages
366 **********************************************************************/
367 static void
368os2_formatmsg(char *msgbuf, int msglen, char *reason)
369{
370 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
371
372 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
373 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
374
375 while (lastc > msgbuf && isspace(*lastc))
376 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
377 }
378
379 /* Add Optional Reason Text */
380 if (reason) {
381 strcat(msgbuf, " : ");
382 strcat(msgbuf, reason);
383 }
384}
385
386/**********************************************************************
387 * Decode an OS/2 Operating System Error Code
388 *
389 * A convenience function to lookup an OS/2 error code and return a
390 * text message we can use to raise a Python exception.
391 *
392 * Notes:
393 * The messages for errors returned from the OS/2 kernel reside in
394 * the file OSO001.MSG in the \OS2 directory hierarchy.
395 *
396 **********************************************************************/
397 static char *
398os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
399{
400 APIRET rc;
401 ULONG msglen;
402
403 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
404 Py_BEGIN_ALLOW_THREADS
405 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
406 errorcode, "oso001.msg", &msglen);
407 Py_END_ALLOW_THREADS
408
409 if (rc == NO_ERROR)
410 os2_formatmsg(msgbuf, msglen, reason);
411 else
412 sprintf(msgbuf, "unknown OS error #%d", errorcode);
413
414 return msgbuf;
415}
416
417/* Set an OS/2-specific error and return NULL. OS/2 kernel
418 errors are not in a global variable e.g. 'errno' nor are
419 they congruent with posix error numbers. */
420
421static PyObject * os2_error(int code)
422{
423 char text[1024];
424 PyObject *v;
425
426 os2_strerror(text, sizeof(text), code, "");
427
428 v = Py_BuildValue("(is)", code, text);
429 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000430 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000431 Py_DECREF(v);
432 }
433 return NULL; /* Signal to Python that an Exception is Pending */
434}
435
436#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000437
438/* POSIX generic methods */
439
Barry Warsaw53699e91996-12-10 23:23:01 +0000440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000441posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000442{
443 int fd;
444 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000445 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000446 return NULL;
447 Py_BEGIN_ALLOW_THREADS
448 res = (*func)(fd);
449 Py_END_ALLOW_THREADS
450 if (res < 0)
451 return posix_error();
452 Py_INCREF(Py_None);
453 return Py_None;
454}
455
456
457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000458posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000460 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000461 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000462 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000463 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000464 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000465 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000466 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000467 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000468 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000469 Py_INCREF(Py_None);
470 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000471}
472
Barry Warsaw53699e91996-12-10 23:23:01 +0000473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000474posix_2str(PyObject *args, char *format,
475 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000476{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000477 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000478 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000479 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000480 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000481 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000482 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000483 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000484 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000485 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000487 Py_INCREF(Py_None);
488 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489}
490
Fred Drake699f3522000-06-29 21:12:41 +0000491/* pack a system stat C structure into the Python stat tuple
492 (used by posix_stat() and posix_fstat()) */
493static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000494_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000495{
496 PyObject *v = PyTuple_New(10);
497 if (v == NULL)
498 return NULL;
499
500 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
501#ifdef HAVE_LARGEFILE_SUPPORT
502 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
503#else
504 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
505#endif
506#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
507 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
508#else
509 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
510#endif
511 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
512 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
513 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
514#ifdef HAVE_LARGEFILE_SUPPORT
515 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
516#else
517 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
518#endif
519#if SIZEOF_TIME_T > SIZEOF_LONG
520 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
521 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
522 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
523#else
524 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
525 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
526 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
527#endif
528
529 if (PyErr_Occurred()) {
530 Py_DECREF(v);
531 return NULL;
532 }
533
534 return v;
535}
536
537
Barry Warsaw53699e91996-12-10 23:23:01 +0000538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000539posix_do_stat(PyObject *self, PyObject *args, char *format,
540 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000541{
Fred Drake699f3522000-06-29 21:12:41 +0000542 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000543 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000544 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000545
546#ifdef MS_WIN32
547 int pathlen;
548 char pathcopy[MAX_PATH];
549#endif /* MS_WIN32 */
550
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000551 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000552 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000553
554#ifdef MS_WIN32
555 pathlen = strlen(path);
556 /* the library call can blow up if the file name is too long! */
557 if (pathlen > MAX_PATH) {
558 errno = ENAMETOOLONG;
559 return posix_error();
560 }
561
562 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000563 /* exception for specific or current drive root */
564 if (!((pathlen == 1) ||
565 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000566 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000567 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000568 {
569 strncpy(pathcopy, path, pathlen);
570 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
571 path = pathcopy;
572 }
573 }
574#endif /* MS_WIN32 */
575
Barry Warsaw53699e91996-12-10 23:23:01 +0000576 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000577 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000578 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000579 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000580 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000581
582 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000583}
584
585
586/* POSIX methods */
587
Guido van Rossum94f6f721999-01-06 18:42:14 +0000588static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000589"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000590Test for access to a file.";
591
592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000593posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000594{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000595 char *path;
596 int mode;
597 int res;
598
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000599 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000600 return NULL;
601 Py_BEGIN_ALLOW_THREADS
602 res = access(path, mode);
603 Py_END_ALLOW_THREADS
604 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000605}
606
Guido van Rossumd371ff11999-01-25 16:12:23 +0000607#ifndef F_OK
608#define F_OK 0
609#endif
610#ifndef R_OK
611#define R_OK 4
612#endif
613#ifndef W_OK
614#define W_OK 2
615#endif
616#ifndef X_OK
617#define X_OK 1
618#endif
619
620#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000621static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000622"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000623Return the name of the terminal device connected to 'fd'.";
624
625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000626posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000627{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000628 int id;
629 char *ret;
630
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000631 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000632 return NULL;
633
Guido van Rossum94f6f721999-01-06 18:42:14 +0000634 ret = ttyname(id);
635 if (ret == NULL)
636 return(posix_error());
637 return(PyString_FromString(ret));
638}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000639#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000640
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000641#ifdef HAVE_CTERMID
642static char posix_ctermid__doc__[] =
643"ctermid() -> String\n\
644Return the name of the controlling terminal for this process.";
645
646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000647posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000648{
649 char *ret;
650 char buffer[L_ctermid];
651
652 if (!PyArg_ParseTuple(args, ":ctermid"))
653 return NULL;
654
Greg Wardb48bc172000-03-01 21:51:56 +0000655#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000656 ret = ctermid_r(buffer);
657#else
658 ret = ctermid(buffer);
659#endif
660 if (ret == NULL)
661 return(posix_error());
662 return(PyString_FromString(buffer));
663}
664#endif
665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000666static char posix_chdir__doc__[] =
667"chdir(path) -> None\n\
668Change the current working directory to the specified path.";
669
Barry Warsaw53699e91996-12-10 23:23:01 +0000670static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000671posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000672{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000673 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000674}
675
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000676
677static char posix_chmod__doc__[] =
678"chmod(path, mode) -> None\n\
679Change the access permissions of a file.";
680
Barry Warsaw53699e91996-12-10 23:23:01 +0000681static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000682posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000683{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000684 char *path;
685 int i;
686 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000687 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000688 return NULL;
689 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000690 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000691 Py_END_ALLOW_THREADS
692 if (res < 0)
693 return posix_error_with_filename(path);
694 Py_INCREF(Py_None);
695 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000696}
697
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000698
Guido van Rossum21142a01999-01-08 21:05:37 +0000699#ifdef HAVE_FSYNC
700static char posix_fsync__doc__[] =
701"fsync(fildes) -> None\n\
702force write of file with filedescriptor to disk.";
703
704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000705posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000706{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000707 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000708}
709#endif /* HAVE_FSYNC */
710
711#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000712
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000713#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000714extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
715#endif
716
Guido van Rossum21142a01999-01-08 21:05:37 +0000717static char posix_fdatasync__doc__[] =
718"fdatasync(fildes) -> None\n\
719force write of file with filedescriptor to disk.\n\
720 does not force update of metadata.";
721
722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000723posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000724{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000725 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000726}
727#endif /* HAVE_FDATASYNC */
728
729
Fredrik Lundh10723342000-07-10 16:38:09 +0000730#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000731static char posix_chown__doc__[] =
732"chown(path, uid, gid) -> None\n\
733Change the owner and group id of path to the numeric uid and gid.";
734
Barry Warsaw53699e91996-12-10 23:23:01 +0000735static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000736posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000737{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000738 char *path;
739 int uid, gid;
740 int res;
741 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
742 return NULL;
743 Py_BEGIN_ALLOW_THREADS
744 res = chown(path, (uid_t) uid, (gid_t) gid);
745 Py_END_ALLOW_THREADS
746 if (res < 0)
747 return posix_error_with_filename(path);
748 Py_INCREF(Py_None);
749 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000750}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000751#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000753
Guido van Rossum36bc6801995-06-14 22:54:23 +0000754#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000755static char posix_getcwd__doc__[] =
756"getcwd() -> path\n\
757Return a string representing the current working directory.";
758
Barry Warsaw53699e91996-12-10 23:23:01 +0000759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000760posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000761{
762 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000763 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000764 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000766 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000767 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000768 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000769 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000770 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000771 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000772}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000773#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000775
Guido van Rossumb6775db1994-08-01 11:34:53 +0000776#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000777static char posix_link__doc__[] =
778"link(src, dst) -> None\n\
779Create a hard link to a file.";
780
Barry Warsaw53699e91996-12-10 23:23:01 +0000781static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000782posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000783{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000784 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000785}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000786#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000788
789static char posix_listdir__doc__[] =
790"listdir(path) -> list_of_strings\n\
791Return a list containing the names of the entries in the directory.\n\
792\n\
793 path: path of directory to list\n\
794\n\
795The list is in arbitrary order. It does not include the special\n\
796entries '.' and '..' even if they are present in the directory.";
797
Barry Warsaw53699e91996-12-10 23:23:01 +0000798static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000799posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000800{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000801 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000802 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000803#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000804
Guido van Rossumb6775db1994-08-01 11:34:53 +0000805 char *name;
806 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000807 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000808 HANDLE hFindFile;
809 WIN32_FIND_DATA FileData;
810 char namebuf[MAX_PATH+5];
Tim Peters0bb44a42000-09-15 07:44:49 +0000811 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000812
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000813 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000814 return NULL;
815 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000816 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000817 return NULL;
818 }
819 strcpy(namebuf, name);
Tim Peters0bb44a42000-09-15 07:44:49 +0000820 ch = namebuf[len-1];
821 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000822 namebuf[len++] = '/';
823 strcpy(namebuf + len, "*.*");
824
Barry Warsaw53699e91996-12-10 23:23:01 +0000825 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000826 return NULL;
827
828 hFindFile = FindFirstFile(namebuf, &FileData);
829 if (hFindFile == INVALID_HANDLE_VALUE) {
830 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000831 if (errno == ERROR_FILE_NOT_FOUND)
832 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000833 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000834 }
835 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000836 if (FileData.cFileName[0] == '.' &&
837 (FileData.cFileName[1] == '\0' ||
838 FileData.cFileName[1] == '.' &&
839 FileData.cFileName[2] == '\0'))
840 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000841 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000842 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000843 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000844 d = NULL;
845 break;
846 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000847 if (PyList_Append(d, v) != 0) {
848 Py_DECREF(v);
849 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000850 d = NULL;
851 break;
852 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000853 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000854 } while (FindNextFile(hFindFile, &FileData) == TRUE);
855
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000856 if (FindClose(hFindFile) == FALSE)
857 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000858
859 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000860
Tim Peters0bb44a42000-09-15 07:44:49 +0000861#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000862
863#ifndef MAX_PATH
864#define MAX_PATH 250
865#endif
866 char *name, *pt;
867 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000868 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000869 char namebuf[MAX_PATH+5];
870 struct _find_t ep;
871
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000872 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000873 return NULL;
874 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000875 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000876 return NULL;
877 }
878 strcpy(namebuf, name);
879 for (pt = namebuf; *pt; pt++)
880 if (*pt == '/')
881 *pt = '\\';
882 if (namebuf[len-1] != '\\')
883 namebuf[len++] = '\\';
884 strcpy(namebuf + len, "*.*");
885
Barry Warsaw53699e91996-12-10 23:23:01 +0000886 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000887 return NULL;
888
889 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000890 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
891 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000892 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000893 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000894 }
895 do {
896 if (ep.name[0] == '.' &&
897 (ep.name[1] == '\0' ||
898 ep.name[1] == '.' &&
899 ep.name[2] == '\0'))
900 continue;
901 strcpy(namebuf, ep.name);
902 for (pt = namebuf; *pt; pt++)
903 if (isupper(*pt))
904 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000905 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000906 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000907 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000908 d = NULL;
909 break;
910 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000911 if (PyList_Append(d, v) != 0) {
912 Py_DECREF(v);
913 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000914 d = NULL;
915 break;
916 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000917 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000918 } while (_dos_findnext(&ep) == 0);
919
920 return d;
921
Tim Peters0bb44a42000-09-15 07:44:49 +0000922#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000923
924#ifndef MAX_PATH
925#define MAX_PATH CCHMAXPATH
926#endif
927 char *name, *pt;
928 int len;
929 PyObject *d, *v;
930 char namebuf[MAX_PATH+5];
931 HDIR hdir = 1;
932 ULONG srchcnt = 1;
933 FILEFINDBUF3 ep;
934 APIRET rc;
935
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000936 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000937 return NULL;
938 if (len >= MAX_PATH) {
939 PyErr_SetString(PyExc_ValueError, "path too long");
940 return NULL;
941 }
942 strcpy(namebuf, name);
943 for (pt = namebuf; *pt; pt++)
944 if (*pt == '/')
945 *pt = '\\';
946 if (namebuf[len-1] != '\\')
947 namebuf[len++] = '\\';
948 strcpy(namebuf + len, "*.*");
949
950 if ((d = PyList_New(0)) == NULL)
951 return NULL;
952
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000953 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
954 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000955 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000956 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
957 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
958 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959
960 if (rc != NO_ERROR) {
961 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000962 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963 }
964
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000965 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000966 do {
967 if (ep.achName[0] == '.'
968 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000969 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000970
971 strcpy(namebuf, ep.achName);
972
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000973 /* Leave Case of Name Alone -- In Native Form */
974 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000975
976 v = PyString_FromString(namebuf);
977 if (v == NULL) {
978 Py_DECREF(d);
979 d = NULL;
980 break;
981 }
982 if (PyList_Append(d, v) != 0) {
983 Py_DECREF(v);
984 Py_DECREF(d);
985 d = NULL;
986 break;
987 }
988 Py_DECREF(v);
989 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
990 }
991
992 return d;
993#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000994
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000995 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +0000996 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000997 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000998 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000999 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001000 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001001 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001002 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001003 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001004 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001005 closedir(dirp);
1006 return NULL;
1007 }
1008 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001009 if (ep->d_name[0] == '.' &&
1010 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001011 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001012 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001013 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001014 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001015 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001016 d = NULL;
1017 break;
1018 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001019 if (PyList_Append(d, v) != 0) {
1020 Py_DECREF(v);
1021 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001022 d = NULL;
1023 break;
1024 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001025 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001026 }
1027 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001028
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001029 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001030
Tim Peters0bb44a42000-09-15 07:44:49 +00001031#endif /* which OS */
1032} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001034static char posix_mkdir__doc__[] =
1035"mkdir(path [, mode=0777]) -> None\n\
1036Create a directory.";
1037
Barry Warsaw53699e91996-12-10 23:23:01 +00001038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001039posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001040{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001041 int res;
1042 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001043 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001044 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001045 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001046 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001047#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001048 res = mkdir(path);
1049#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001050 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001051#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001052 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001053 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001054 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001055 Py_INCREF(Py_None);
1056 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001057}
1058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001059
Guido van Rossumb6775db1994-08-01 11:34:53 +00001060#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001061static char posix_nice__doc__[] =
1062"nice(inc) -> new_priority\n\
1063Decrease the priority of process and return new priority.";
1064
Barry Warsaw53699e91996-12-10 23:23:01 +00001065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001066posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001067{
1068 int increment, value;
1069
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001070 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001071 return NULL;
1072 value = nice(increment);
1073 if (value == -1)
1074 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001075 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001076}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001077#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001078
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001079
1080static char posix_rename__doc__[] =
1081"rename(old, new) -> None\n\
1082Rename a file or directory.";
1083
Barry Warsaw53699e91996-12-10 23:23:01 +00001084static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001085posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001086{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001087 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001088}
1089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001090
1091static char posix_rmdir__doc__[] =
1092"rmdir(path) -> None\n\
1093Remove a directory.";
1094
Barry Warsaw53699e91996-12-10 23:23:01 +00001095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001096posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001097{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001098 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001099}
1100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001101
1102static char posix_stat__doc__[] =
1103"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1104Perform a stat system call on the given path.";
1105
Barry Warsaw53699e91996-12-10 23:23:01 +00001106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001107posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001108{
Fred Drake699f3522000-06-29 21:12:41 +00001109 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001110}
1111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001112
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001113#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001114static char posix_system__doc__[] =
1115"system(command) -> exit_status\n\
1116Execute the command (a string) in a subshell.";
1117
Barry Warsaw53699e91996-12-10 23:23:01 +00001118static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001119posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001120{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001121 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001122 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001123 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001125 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001126 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001127 Py_END_ALLOW_THREADS
1128 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001129}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001130#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001132
1133static char posix_umask__doc__[] =
1134"umask(new_mask) -> old_mask\n\
1135Set the current numeric umask and return the previous umask.";
1136
Barry Warsaw53699e91996-12-10 23:23:01 +00001137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001138posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001139{
1140 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001141 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142 return NULL;
1143 i = umask(i);
1144 if (i < 0)
1145 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001146 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001147}
1148
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001149
1150static char posix_unlink__doc__[] =
1151"unlink(path) -> None\n\
1152Remove a file (same as remove(path)).";
1153
1154static char posix_remove__doc__[] =
1155"remove(path) -> None\n\
1156Remove a file (same as unlink(path)).";
1157
Barry Warsaw53699e91996-12-10 23:23:01 +00001158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001159posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001160{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001161 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162}
1163
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001164
Guido van Rossumb6775db1994-08-01 11:34:53 +00001165#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001166static char posix_uname__doc__[] =
1167"uname() -> (sysname, nodename, release, version, machine)\n\
1168Return a tuple identifying the current operating system.";
1169
Barry Warsaw53699e91996-12-10 23:23:01 +00001170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001171posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001172{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001173 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001174 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001175 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001176 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001177 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001178 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001179 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001180 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001181 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001182 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001183 u.sysname,
1184 u.nodename,
1185 u.release,
1186 u.version,
1187 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001188}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001189#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001191
1192static char posix_utime__doc__[] =
1193"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001194utime(path, None) -> None\n\
1195Set the access and modified time of the file to the given values. If the\n\
1196second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001197
Barry Warsaw53699e91996-12-10 23:23:01 +00001198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001199posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001200{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001201 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001202 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001203 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001204 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001205
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001206/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001207#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001208 struct utimbuf buf;
1209#define ATIME buf.actime
1210#define MTIME buf.modtime
1211#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001212#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001213 time_t buf[2];
1214#define ATIME buf[0]
1215#define MTIME buf[1]
1216#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001217#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001218
Barry Warsaw3cef8562000-05-01 16:17:24 +00001219 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001220 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001221 if (arg == Py_None) {
1222 /* optional time values not given */
1223 Py_BEGIN_ALLOW_THREADS
1224 res = utime(path, NULL);
1225 Py_END_ALLOW_THREADS
1226 }
1227 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1228 PyErr_SetString(PyExc_TypeError,
1229 "Second argument must be a 2-tuple of numbers.");
1230 return NULL;
1231 }
1232 else {
1233 ATIME = atime;
1234 MTIME = mtime;
1235 Py_BEGIN_ALLOW_THREADS
1236 res = utime(path, UTIME_ARG);
1237 Py_END_ALLOW_THREADS
1238 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001239 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001240 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001241 Py_INCREF(Py_None);
1242 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001243#undef UTIME_ARG
1244#undef ATIME
1245#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001246}
1247
Guido van Rossum85e3b011991-06-03 12:42:10 +00001248
Guido van Rossum3b066191991-06-04 19:40:25 +00001249/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001251static char posix__exit__doc__[] =
1252"_exit(status)\n\
1253Exit to the system with specified status, without normal exit processing.";
1254
Barry Warsaw53699e91996-12-10 23:23:01 +00001255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001256posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001257{
1258 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001259 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001260 return NULL;
1261 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001262 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001263}
1264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001265
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001266#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001267static char posix_execv__doc__[] =
1268"execv(path, args)\n\
1269Execute an executable path with arguments, replacing current process.\n\
1270\n\
1271 path: path of executable file\n\
1272 args: tuple or list of strings";
1273
Barry Warsaw53699e91996-12-10 23:23:01 +00001274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001275posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001276{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001277 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001278 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001279 char **argvlist;
1280 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001281 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001282
Guido van Rossum89b33251993-10-22 14:26:06 +00001283 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001284 argv is a list or tuple of strings. */
1285
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001286 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001287 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001288 if (PyList_Check(argv)) {
1289 argc = PyList_Size(argv);
1290 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001291 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001292 else if (PyTuple_Check(argv)) {
1293 argc = PyTuple_Size(argv);
1294 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001295 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001296 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001297 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1298 return NULL;
1299 }
1300
1301 if (argc == 0) {
1302 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001303 return NULL;
1304 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001305
Barry Warsaw53699e91996-12-10 23:23:01 +00001306 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001307 if (argvlist == NULL)
1308 return NULL;
1309 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001310 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1311 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001312 PyErr_SetString(PyExc_TypeError,
1313 "all arguments must be strings");
1314 return NULL;
1315
Guido van Rossum85e3b011991-06-03 12:42:10 +00001316 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001317 }
1318 argvlist[argc] = NULL;
1319
Guido van Rossumb6775db1994-08-01 11:34:53 +00001320#ifdef BAD_EXEC_PROTOTYPES
1321 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001322#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001323 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001324#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001325
Guido van Rossum85e3b011991-06-03 12:42:10 +00001326 /* If we get here it's definitely an error */
1327
Barry Warsaw53699e91996-12-10 23:23:01 +00001328 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001329 return posix_error();
1330}
1331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001332
1333static char posix_execve__doc__[] =
1334"execve(path, args, env)\n\
1335Execute a path with arguments and environment, replacing current process.\n\
1336\n\
1337 path: path of executable file\n\
1338 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001339 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001340
Barry Warsaw53699e91996-12-10 23:23:01 +00001341static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001342posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001343{
1344 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001345 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001346 char **argvlist;
1347 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001348 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001349 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001350 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001351
1352 /* execve has three arguments: (path, argv, env), where
1353 argv is a list or tuple of strings and env is a dictionary
1354 like posix.environ. */
1355
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001356 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001357 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001358 if (PyList_Check(argv)) {
1359 argc = PyList_Size(argv);
1360 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001361 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001362 else if (PyTuple_Check(argv)) {
1363 argc = PyTuple_Size(argv);
1364 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001365 }
1366 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001367 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001368 return NULL;
1369 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001370 if (!PyMapping_Check(env)) {
1371 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001372 return NULL;
1373 }
1374
Guido van Rossum50422b42000-04-26 20:34:28 +00001375 if (argc == 0) {
1376 PyErr_SetString(PyExc_ValueError,
1377 "empty argument list");
1378 return NULL;
1379 }
1380
Barry Warsaw53699e91996-12-10 23:23:01 +00001381 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001382 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001383 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001384 return NULL;
1385 }
1386 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001387 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001388 "s;argv must be list of strings",
1389 &argvlist[i]))
1390 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001391 goto fail_1;
1392 }
1393 }
1394 argvlist[argc] = NULL;
1395
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001396 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001397 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001398 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001399 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001400 goto fail_1;
1401 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001402 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001403 keys = PyMapping_Keys(env);
1404 vals = PyMapping_Values(env);
1405 if (!keys || !vals)
1406 goto fail_2;
1407
1408 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001409 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001410
1411 key = PyList_GetItem(keys, pos);
1412 val = PyList_GetItem(vals, pos);
1413 if (!key || !val)
1414 goto fail_2;
1415
Barry Warsaw53699e91996-12-10 23:23:01 +00001416 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001417 !PyArg_Parse(val, "s;non-string value in env", &v))
1418 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001419 goto fail_2;
1420 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001421
1422#if defined(PYOS_OS2)
1423 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1424 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1425#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001426 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001427 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001428 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001429 goto fail_2;
1430 }
1431 sprintf(p, "%s=%s", k, v);
1432 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001433#if defined(PYOS_OS2)
1434 }
1435#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001436 }
1437 envlist[envc] = 0;
1438
Guido van Rossumb6775db1994-08-01 11:34:53 +00001439
1440#ifdef BAD_EXEC_PROTOTYPES
1441 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001442#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001443 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001444#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001445
1446 /* If we get here it's definitely an error */
1447
1448 (void) posix_error();
1449
1450 fail_2:
1451 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001452 PyMem_DEL(envlist[envc]);
1453 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001454 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001455 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001456 Py_XDECREF(vals);
1457 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001458 return NULL;
1459}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001460#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001461
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001462
Guido van Rossuma1065681999-01-25 23:20:23 +00001463#ifdef HAVE_SPAWNV
1464static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001465"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001466Execute an executable path with arguments, replacing current process.\n\
1467\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001468 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001469 path: path of executable file\n\
1470 args: tuple or list of strings";
1471
1472static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001473posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001474{
1475 char *path;
1476 PyObject *argv;
1477 char **argvlist;
1478 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001479 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001480 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001481
1482 /* spawnv has three arguments: (mode, path, argv), where
1483 argv is a list or tuple of strings. */
1484
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001485 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001486 return NULL;
1487 if (PyList_Check(argv)) {
1488 argc = PyList_Size(argv);
1489 getitem = PyList_GetItem;
1490 }
1491 else if (PyTuple_Check(argv)) {
1492 argc = PyTuple_Size(argv);
1493 getitem = PyTuple_GetItem;
1494 }
1495 else {
Fred Drake137507e2000-06-01 02:02:46 +00001496 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001497 return NULL;
1498 }
1499
1500 argvlist = PyMem_NEW(char *, argc+1);
1501 if (argvlist == NULL)
1502 return NULL;
1503 for (i = 0; i < argc; i++) {
1504 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1505 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001506 PyErr_SetString(PyExc_TypeError,
1507 "all arguments must be strings");
1508 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001509 }
1510 }
1511 argvlist[argc] = NULL;
1512
Guido van Rossum246bc171999-02-01 23:54:31 +00001513 if (mode == _OLD_P_OVERLAY)
1514 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001515 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001516
1517 PyMem_DEL(argvlist);
1518
Fred Drake699f3522000-06-29 21:12:41 +00001519 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001520 return posix_error();
1521 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001522#if SIZEOF_LONG == SIZEOF_VOID_P
1523 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001524#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001525 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001526#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001527}
1528
1529
1530static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001531"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001532Execute a path with arguments and environment, replacing current process.\n\
1533\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001534 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001535 path: path of executable file\n\
1536 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001537 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001538
1539static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001540posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001541{
1542 char *path;
1543 PyObject *argv, *env;
1544 char **argvlist;
1545 char **envlist;
1546 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1547 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001548 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001549 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001550
1551 /* spawnve has four arguments: (mode, path, argv, env), where
1552 argv is a list or tuple of strings and env is a dictionary
1553 like posix.environ. */
1554
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001555 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001556 return NULL;
1557 if (PyList_Check(argv)) {
1558 argc = PyList_Size(argv);
1559 getitem = PyList_GetItem;
1560 }
1561 else if (PyTuple_Check(argv)) {
1562 argc = PyTuple_Size(argv);
1563 getitem = PyTuple_GetItem;
1564 }
1565 else {
1566 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1567 return NULL;
1568 }
1569 if (!PyMapping_Check(env)) {
1570 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1571 return NULL;
1572 }
1573
1574 argvlist = PyMem_NEW(char *, argc+1);
1575 if (argvlist == NULL) {
1576 PyErr_NoMemory();
1577 return NULL;
1578 }
1579 for (i = 0; i < argc; i++) {
1580 if (!PyArg_Parse((*getitem)(argv, i),
1581 "s;argv must be list of strings",
1582 &argvlist[i]))
1583 {
1584 goto fail_1;
1585 }
1586 }
1587 argvlist[argc] = NULL;
1588
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001589 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001590 envlist = PyMem_NEW(char *, i + 1);
1591 if (envlist == NULL) {
1592 PyErr_NoMemory();
1593 goto fail_1;
1594 }
1595 envc = 0;
1596 keys = PyMapping_Keys(env);
1597 vals = PyMapping_Values(env);
1598 if (!keys || !vals)
1599 goto fail_2;
1600
1601 for (pos = 0; pos < i; pos++) {
1602 char *p, *k, *v;
1603
1604 key = PyList_GetItem(keys, pos);
1605 val = PyList_GetItem(vals, pos);
1606 if (!key || !val)
1607 goto fail_2;
1608
1609 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1610 !PyArg_Parse(val, "s;non-string value in env", &v))
1611 {
1612 goto fail_2;
1613 }
1614 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1615 if (p == NULL) {
1616 PyErr_NoMemory();
1617 goto fail_2;
1618 }
1619 sprintf(p, "%s=%s", k, v);
1620 envlist[envc++] = p;
1621 }
1622 envlist[envc] = 0;
1623
Guido van Rossum246bc171999-02-01 23:54:31 +00001624 if (mode == _OLD_P_OVERLAY)
1625 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001626 spawnval = _spawnve(mode, path, argvlist, envlist);
1627 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001628 (void) posix_error();
1629 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001630#if SIZEOF_LONG == SIZEOF_VOID_P
1631 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001632#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001633 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001634#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001635
1636 fail_2:
1637 while (--envc >= 0)
1638 PyMem_DEL(envlist[envc]);
1639 PyMem_DEL(envlist);
1640 fail_1:
1641 PyMem_DEL(argvlist);
1642 Py_XDECREF(vals);
1643 Py_XDECREF(keys);
1644 return res;
1645}
1646#endif /* HAVE_SPAWNV */
1647
1648
Guido van Rossumad0ee831995-03-01 10:34:45 +00001649#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001650static char posix_fork__doc__[] =
1651"fork() -> pid\n\
1652Fork a child process.\n\
1653\n\
1654Return 0 to child process and PID of child to parent process.";
1655
Barry Warsaw53699e91996-12-10 23:23:01 +00001656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001657posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001658{
1659 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001660 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001661 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001662 pid = fork();
1663 if (pid == -1)
1664 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001665 if (pid == 0)
1666 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001667 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001668}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001669#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001670
Fred Drake8cef4cf2000-06-28 16:40:38 +00001671#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1672#ifdef HAVE_PTY_H
1673#include <pty.h>
1674#else
1675#ifdef HAVE_LIBUTIL_H
1676#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001677#endif /* HAVE_LIBUTIL_H */
1678#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001679#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001680
Thomas Wouters70c21a12000-07-14 14:28:33 +00001681#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001682static char posix_openpty__doc__[] =
1683"openpty() -> (master_fd, slave_fd)\n\
1684Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1685
1686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001687posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001688{
1689 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001690#ifndef HAVE_OPENPTY
1691 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001692#endif
1693
Fred Drake8cef4cf2000-06-28 16:40:38 +00001694 if (!PyArg_ParseTuple(args, ":openpty"))
1695 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001696
1697#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001698 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1699 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001700#else
1701 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1702 if (slave_name == NULL)
1703 return posix_error();
1704
1705 slave_fd = open(slave_name, O_RDWR);
1706 if (slave_fd < 0)
1707 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001708#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001709
Fred Drake8cef4cf2000-06-28 16:40:38 +00001710 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001711
Fred Drake8cef4cf2000-06-28 16:40:38 +00001712}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001713#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001714
1715#ifdef HAVE_FORKPTY
1716static char posix_forkpty__doc__[] =
1717"forkpty() -> (pid, master_fd)\n\
1718Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1719Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1720To both, return fd of newly opened pseudo-terminal.\n";
1721
1722static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001723posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001724{
1725 int master_fd, pid;
1726
1727 if (!PyArg_ParseTuple(args, ":forkpty"))
1728 return NULL;
1729 pid = forkpty(&master_fd, NULL, NULL, NULL);
1730 if (pid == -1)
1731 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001732 if (pid == 0)
1733 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001734 return Py_BuildValue("(ii)", pid, master_fd);
1735}
1736#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001737
Guido van Rossumad0ee831995-03-01 10:34:45 +00001738#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001739static char posix_getegid__doc__[] =
1740"getegid() -> egid\n\
1741Return the current process's effective group id.";
1742
Barry Warsaw53699e91996-12-10 23:23:01 +00001743static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001744posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001745{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001746 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001747 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001748 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001749}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001750#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001752
Guido van Rossumad0ee831995-03-01 10:34:45 +00001753#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001754static char posix_geteuid__doc__[] =
1755"geteuid() -> euid\n\
1756Return the current process's effective user id.";
1757
Barry Warsaw53699e91996-12-10 23:23:01 +00001758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001759posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001760{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001761 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001762 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001763 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001764}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001765#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001766
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001767
Guido van Rossumad0ee831995-03-01 10:34:45 +00001768#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001769static char posix_getgid__doc__[] =
1770"getgid() -> gid\n\
1771Return the current process's group id.";
1772
Barry Warsaw53699e91996-12-10 23:23:01 +00001773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001774posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001775{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001776 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001777 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001778 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001779}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001780#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001781
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001782
1783static char posix_getpid__doc__[] =
1784"getpid() -> pid\n\
1785Return the current process id";
1786
Barry Warsaw53699e91996-12-10 23:23:01 +00001787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001788posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001789{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001790 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001791 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001792 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001793}
1794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001795
Fred Drakec9680921999-12-13 16:37:25 +00001796#ifdef HAVE_GETGROUPS
1797static char posix_getgroups__doc__[] = "\
1798getgroups() -> list of group IDs\n\
1799Return list of supplemental group IDs for the process.";
1800
1801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001802posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001803{
1804 PyObject *result = NULL;
1805
1806 if (PyArg_ParseTuple(args, ":getgroups")) {
1807#ifdef NGROUPS_MAX
1808#define MAX_GROUPS NGROUPS_MAX
1809#else
1810 /* defined to be 16 on Solaris7, so this should be a small number */
1811#define MAX_GROUPS 64
1812#endif
1813 gid_t grouplist[MAX_GROUPS];
1814 int n;
1815
1816 n = getgroups(MAX_GROUPS, grouplist);
1817 if (n < 0)
1818 posix_error();
1819 else {
1820 result = PyList_New(n);
1821 if (result != NULL) {
1822 PyObject *o;
1823 int i;
1824 for (i = 0; i < n; ++i) {
1825 o = PyInt_FromLong((long)grouplist[i]);
1826 if (o == NULL) {
1827 Py_DECREF(result);
1828 result = NULL;
1829 break;
1830 }
1831 PyList_SET_ITEM(result, i, o);
1832 }
1833 }
1834 }
1835 }
1836 return result;
1837}
1838#endif
1839
Guido van Rossumb6775db1994-08-01 11:34:53 +00001840#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001841static char posix_getpgrp__doc__[] =
1842"getpgrp() -> pgrp\n\
1843Return the current process group id.";
1844
Barry Warsaw53699e91996-12-10 23:23:01 +00001845static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001846posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001847{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001848 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001849 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001850#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001851 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001852#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001853 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001854#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001855}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001856#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001857
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001858
Guido van Rossumb6775db1994-08-01 11:34:53 +00001859#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001860static char posix_setpgrp__doc__[] =
1861"setpgrp() -> None\n\
1862Make this process a session leader.";
1863
Barry Warsaw53699e91996-12-10 23:23:01 +00001864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001865posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001866{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001867 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001868 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001869#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001870 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001871#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001872 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001873#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001874 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001875 Py_INCREF(Py_None);
1876 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001877}
1878
Guido van Rossumb6775db1994-08-01 11:34:53 +00001879#endif /* HAVE_SETPGRP */
1880
Guido van Rossumad0ee831995-03-01 10:34:45 +00001881#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001882static char posix_getppid__doc__[] =
1883"getppid() -> ppid\n\
1884Return the parent's process id.";
1885
Barry Warsaw53699e91996-12-10 23:23:01 +00001886static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001887posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001888{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001889 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001890 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001891 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001892}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001893#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001894
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001895
Fred Drake12c6e2d1999-12-14 21:25:03 +00001896#ifdef HAVE_GETLOGIN
1897static char posix_getlogin__doc__[] = "\
1898getlogin() -> string\n\
1899Return the actual login name.";
1900
1901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001902posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001903{
1904 PyObject *result = NULL;
1905
1906 if (PyArg_ParseTuple(args, ":getlogin")) {
1907 char *name = getlogin();
1908
1909 if (name == NULL)
1910 posix_error();
1911 else
1912 result = PyString_FromString(name);
1913 }
1914 return result;
1915}
1916#endif
1917
Guido van Rossumad0ee831995-03-01 10:34:45 +00001918#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001919static char posix_getuid__doc__[] =
1920"getuid() -> uid\n\
1921Return the current process's user id.";
1922
Barry Warsaw53699e91996-12-10 23:23:01 +00001923static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001924posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001925{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001926 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001927 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001928 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001929}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001930#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001931
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001932
Guido van Rossumad0ee831995-03-01 10:34:45 +00001933#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001934static char posix_kill__doc__[] =
1935"kill(pid, sig) -> None\n\
1936Kill a process with a signal.";
1937
Barry Warsaw53699e91996-12-10 23:23:01 +00001938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001939posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001940{
1941 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001942 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001943 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001944#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001945 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1946 APIRET rc;
1947 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001948 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001949
1950 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1951 APIRET rc;
1952 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001953 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001954
1955 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001956 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001957#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001958 if (kill(pid, sig) == -1)
1959 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001960#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001961 Py_INCREF(Py_None);
1962 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001963}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001964#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001965
Guido van Rossumc0125471996-06-28 18:55:32 +00001966#ifdef HAVE_PLOCK
1967
1968#ifdef HAVE_SYS_LOCK_H
1969#include <sys/lock.h>
1970#endif
1971
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001972static char posix_plock__doc__[] =
1973"plock(op) -> None\n\
1974Lock program segments into memory.";
1975
Barry Warsaw53699e91996-12-10 23:23:01 +00001976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001977posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001978{
1979 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001980 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001981 return NULL;
1982 if (plock(op) == -1)
1983 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001984 Py_INCREF(Py_None);
1985 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00001986}
1987#endif
1988
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001989
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001990#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001991static char posix_popen__doc__[] =
1992"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
1993Open a pipe to/from a command returning a file object.";
1994
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001995#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001996static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001997async_system(const char *command)
1998{
1999 char *p, errormsg[256], args[1024];
2000 RESULTCODES rcodes;
2001 APIRET rc;
2002 char *shell = getenv("COMSPEC");
2003 if (!shell)
2004 shell = "cmd";
2005
2006 strcpy(args, shell);
2007 p = &args[ strlen(args)+1 ];
2008 strcpy(p, "/c ");
2009 strcat(p, command);
2010 p += strlen(p) + 1;
2011 *p = '\0';
2012
2013 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002014 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002015 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002016 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002017 &rcodes, shell);
2018 return rc;
2019}
2020
Guido van Rossumd48f2521997-12-05 22:19:34 +00002021static FILE *
2022popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002023{
2024 HFILE rhan, whan;
2025 FILE *retfd = NULL;
2026 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2027
Guido van Rossumd48f2521997-12-05 22:19:34 +00002028 if (rc != NO_ERROR) {
2029 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002030 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002031 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002032
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002033 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2034 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002035
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002036 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2037 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002038
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002039 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2040 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002041
2042 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002043 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002044 }
2045
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002046 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2047 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002048
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002049 close(oldfd); /* And Close Saved STDOUT Handle */
2050 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002051
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002052 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2053 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002054
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002055 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2056 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002057
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002058 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2059 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002060
2061 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002062 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002063 }
2064
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002065 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2066 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002067
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002068 close(oldfd); /* And Close Saved STDIN Handle */
2069 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002070
Guido van Rossumd48f2521997-12-05 22:19:34 +00002071 } else {
2072 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002073 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002074 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002075}
2076
2077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002078posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002079{
2080 char *name;
2081 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002082 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002083 FILE *fp;
2084 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002085 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002086 return NULL;
2087 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002088 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002089 Py_END_ALLOW_THREADS
2090 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002091 return os2_error(err);
2092
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002093 f = PyFile_FromFile(fp, name, mode, fclose);
2094 if (f != NULL)
2095 PyFile_SetBufSize(f, bufsize);
2096 return f;
2097}
2098
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002099#elif defined(MS_WIN32)
2100
2101/*
2102 * Portable 'popen' replacement for Win32.
2103 *
2104 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2105 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002106 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002107 */
2108
2109#include <malloc.h>
2110#include <io.h>
2111#include <fcntl.h>
2112
2113/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2114#define POPEN_1 1
2115#define POPEN_2 2
2116#define POPEN_3 3
2117#define POPEN_4 4
2118
2119static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002120static int _PyPclose(FILE *file);
2121
2122/*
2123 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002124 * for use when retrieving the process exit code. See _PyPclose() below
2125 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002126 */
2127static PyObject *_PyPopenProcs = NULL;
2128
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002129
2130/* popen that works from a GUI.
2131 *
2132 * The result of this function is a pipe (file) connected to the
2133 * processes stdin or stdout, depending on the requested mode.
2134 */
2135
2136static PyObject *
2137posix_popen(PyObject *self, PyObject *args)
2138{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002139 PyObject *f, *s;
2140 int tm = 0;
2141
2142 char *cmdstring;
2143 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002144 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002145 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002146 return NULL;
2147
2148 s = PyTuple_New(0);
2149
2150 if (*mode == 'r')
2151 tm = _O_RDONLY;
2152 else if (*mode != 'w') {
2153 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2154 return NULL;
2155 } else
2156 tm = _O_WRONLY;
2157
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002158 if (bufsize != -1) {
2159 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2160 return NULL;
2161 }
2162
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002163 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002164 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002165 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002166 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002167 else
2168 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2169
2170 return f;
2171}
2172
2173/* Variation on win32pipe.popen
2174 *
2175 * The result of this function is a pipe (file) connected to the
2176 * process's stdin, and a pipe connected to the process's stdout.
2177 */
2178
2179static PyObject *
2180win32_popen2(PyObject *self, PyObject *args)
2181{
2182 PyObject *f;
2183 int tm=0;
2184
2185 char *cmdstring;
2186 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002187 int bufsize = -1;
2188 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002189 return NULL;
2190
2191 if (*mode == 't')
2192 tm = _O_TEXT;
2193 else if (*mode != 'b') {
2194 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2195 return NULL;
2196 } else
2197 tm = _O_BINARY;
2198
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002199 if (bufsize != -1) {
2200 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2201 return NULL;
2202 }
2203
2204 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002205
2206 return f;
2207}
2208
2209/*
2210 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002211 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002212 * The result of this function is 3 pipes - the process's stdin,
2213 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002214 */
2215
2216static PyObject *
2217win32_popen3(PyObject *self, PyObject *args)
2218{
2219 PyObject *f;
2220 int tm = 0;
2221
2222 char *cmdstring;
2223 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002224 int bufsize = -1;
2225 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002226 return NULL;
2227
2228 if (*mode == 't')
2229 tm = _O_TEXT;
2230 else if (*mode != 'b') {
2231 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2232 return NULL;
2233 } else
2234 tm = _O_BINARY;
2235
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002236 if (bufsize != -1) {
2237 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2238 return NULL;
2239 }
2240
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002241 f = _PyPopen(cmdstring, tm, POPEN_3);
2242
2243 return f;
2244}
2245
2246/*
2247 * Variation on win32pipe.popen
2248 *
2249 * The result of this function is 2 pipes - the processes stdin,
2250 * and stdout+stderr combined as a single pipe.
2251 */
2252
2253static PyObject *
2254win32_popen4(PyObject *self, PyObject *args)
2255{
2256 PyObject *f;
2257 int tm = 0;
2258
2259 char *cmdstring;
2260 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002261 int bufsize = -1;
2262 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002263 return NULL;
2264
2265 if (*mode == 't')
2266 tm = _O_TEXT;
2267 else if (*mode != 'b') {
2268 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2269 return NULL;
2270 } else
2271 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002272
2273 if (bufsize != -1) {
2274 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2275 return NULL;
2276 }
2277
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002278 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002279
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002280 return f;
2281}
2282
2283static int
Mark Hammondb37a3732000-08-14 04:47:33 +00002284_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002285 HANDLE hStdin,
2286 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002287 HANDLE hStderr,
2288 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002289{
2290 PROCESS_INFORMATION piProcInfo;
2291 STARTUPINFO siStartInfo;
2292 char *s1,*s2, *s3 = " /c ";
2293 const char *szConsoleSpawn = "w9xpopen.exe \"";
2294 int i;
2295 int x;
2296
2297 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2298 s1 = (char *)_alloca(i);
2299 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2300 return x;
2301 if (GetVersion() < 0x80000000) {
2302 /*
2303 * NT/2000
2304 */
2305 x = i + strlen(s3) + strlen(cmdstring) + 1;
2306 s2 = (char *)_alloca(x);
2307 ZeroMemory(s2, x);
2308 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2309 }
2310 else {
2311 /*
2312 * Oh gag, we're on Win9x. Use the workaround listed in
2313 * KB: Q150956
2314 */
2315 char modulepath[256];
2316 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2317 for (i = x = 0; modulepath[i]; i++)
2318 if (modulepath[i] == '\\')
2319 x = i+1;
2320 modulepath[x] = '\0';
2321 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2322 strlen(modulepath) +
2323 strlen(szConsoleSpawn) + 1;
2324 s2 = (char *)_alloca(x);
2325 ZeroMemory(s2, x);
2326 sprintf(
2327 s2,
2328 "%s%s%s%s%s\"",
2329 modulepath,
2330 szConsoleSpawn,
2331 s1,
2332 s3,
2333 cmdstring);
2334 }
2335 }
2336
2337 /* Could be an else here to try cmd.exe / command.com in the path
2338 Now we'll just error out.. */
2339 else
2340 return -1;
2341
2342 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2343 siStartInfo.cb = sizeof(STARTUPINFO);
2344 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2345 siStartInfo.hStdInput = hStdin;
2346 siStartInfo.hStdOutput = hStdout;
2347 siStartInfo.hStdError = hStderr;
2348 siStartInfo.wShowWindow = SW_HIDE;
2349
2350 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002351 s2,
2352 NULL,
2353 NULL,
2354 TRUE,
2355 CREATE_NEW_CONSOLE,
2356 NULL,
2357 NULL,
2358 &siStartInfo,
2359 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002360 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002361 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002362
Mark Hammondb37a3732000-08-14 04:47:33 +00002363 /* Return process handle */
2364 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002365 return TRUE;
2366 }
2367 return FALSE;
2368}
2369
2370/* The following code is based off of KB: Q190351 */
2371
2372static PyObject *
2373_PyPopen(char *cmdstring, int mode, int n)
2374{
2375 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2376 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002377 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002378
2379 SECURITY_ATTRIBUTES saAttr;
2380 BOOL fSuccess;
2381 int fd1, fd2, fd3;
2382 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002383 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002384 PyObject *f;
2385
2386 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2387 saAttr.bInheritHandle = TRUE;
2388 saAttr.lpSecurityDescriptor = NULL;
2389
2390 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2391 return win32_error("CreatePipe", NULL);
2392
2393 /* Create new output read handle and the input write handle. Set
2394 * the inheritance properties to FALSE. Otherwise, the child inherits
2395 * the these handles; resulting in non-closeable handles to the pipes
2396 * being created. */
2397 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002398 GetCurrentProcess(), &hChildStdinWrDup, 0,
2399 FALSE,
2400 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002401 if (!fSuccess)
2402 return win32_error("DuplicateHandle", NULL);
2403
2404 /* Close the inheritable version of ChildStdin
2405 that we're using. */
2406 CloseHandle(hChildStdinWr);
2407
2408 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2409 return win32_error("CreatePipe", NULL);
2410
2411 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002412 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2413 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002414 if (!fSuccess)
2415 return win32_error("DuplicateHandle", NULL);
2416
2417 /* Close the inheritable version of ChildStdout
2418 that we're using. */
2419 CloseHandle(hChildStdoutRd);
2420
2421 if (n != POPEN_4) {
2422 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2423 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002424 fSuccess = DuplicateHandle(GetCurrentProcess(),
2425 hChildStderrRd,
2426 GetCurrentProcess(),
2427 &hChildStderrRdDup, 0,
2428 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002429 if (!fSuccess)
2430 return win32_error("DuplicateHandle", NULL);
2431 /* Close the inheritable version of ChildStdErr that we're using. */
2432 CloseHandle(hChildStderrRd);
2433 }
2434
2435 switch (n) {
2436 case POPEN_1:
2437 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2438 case _O_WRONLY | _O_TEXT:
2439 /* Case for writing to child Stdin in text mode. */
2440 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2441 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002442 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002443 PyFile_SetBufSize(f, 0);
2444 /* We don't care about these pipes anymore, so close them. */
2445 CloseHandle(hChildStdoutRdDup);
2446 CloseHandle(hChildStderrRdDup);
2447 break;
2448
2449 case _O_RDONLY | _O_TEXT:
2450 /* Case for reading from child Stdout in text mode. */
2451 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2452 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002453 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002454 PyFile_SetBufSize(f, 0);
2455 /* We don't care about these pipes anymore, so close them. */
2456 CloseHandle(hChildStdinWrDup);
2457 CloseHandle(hChildStderrRdDup);
2458 break;
2459
2460 case _O_RDONLY | _O_BINARY:
2461 /* Case for readinig from child Stdout in binary mode. */
2462 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2463 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002464 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002465 PyFile_SetBufSize(f, 0);
2466 /* We don't care about these pipes anymore, so close them. */
2467 CloseHandle(hChildStdinWrDup);
2468 CloseHandle(hChildStderrRdDup);
2469 break;
2470
2471 case _O_WRONLY | _O_BINARY:
2472 /* Case for writing to child Stdin in binary mode. */
2473 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2474 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002475 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002476 PyFile_SetBufSize(f, 0);
2477 /* We don't care about these pipes anymore, so close them. */
2478 CloseHandle(hChildStdoutRdDup);
2479 CloseHandle(hChildStderrRdDup);
2480 break;
2481 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002482 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002483 break;
2484
2485 case POPEN_2:
2486 case POPEN_4:
2487 {
2488 char *m1, *m2;
2489 PyObject *p1, *p2;
2490
2491 if (mode && _O_TEXT) {
2492 m1 = "r";
2493 m2 = "w";
2494 } else {
2495 m1 = "rb";
2496 m2 = "wb";
2497 }
2498
2499 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2500 f1 = _fdopen(fd1, m2);
2501 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2502 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002503 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002504 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002505 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002506 PyFile_SetBufSize(p2, 0);
2507
2508 if (n != 4)
2509 CloseHandle(hChildStderrRdDup);
2510
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002511 f = Py_BuildValue("OO",p1,p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002512 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002513 break;
2514 }
2515
2516 case POPEN_3:
2517 {
2518 char *m1, *m2;
2519 PyObject *p1, *p2, *p3;
2520
2521 if (mode && _O_TEXT) {
2522 m1 = "r";
2523 m2 = "w";
2524 } else {
2525 m1 = "rb";
2526 m2 = "wb";
2527 }
2528
2529 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2530 f1 = _fdopen(fd1, m2);
2531 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2532 f2 = _fdopen(fd2, m1);
2533 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2534 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002535 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002536 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2537 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002538 PyFile_SetBufSize(p1, 0);
2539 PyFile_SetBufSize(p2, 0);
2540 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002541 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002542 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002543 break;
2544 }
2545 }
2546
2547 if (n == POPEN_4) {
2548 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002549 hChildStdinRd,
2550 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002551 hChildStdoutWr,
2552 &hProcess))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002553 return win32_error("CreateProcess", NULL);
2554 }
2555 else {
2556 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002557 hChildStdinRd,
2558 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002559 hChildStderrWr,
2560 &hProcess))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002561 return win32_error("CreateProcess", NULL);
2562 }
2563
Mark Hammondb37a3732000-08-14 04:47:33 +00002564 /*
2565 * Insert the files we've created into the process dictionary
2566 * all referencing the list with the process handle and the
2567 * initial number of files (see description below in _PyPclose).
2568 * Since if _PyPclose later tried to wait on a process when all
2569 * handles weren't closed, it could create a deadlock with the
2570 * child, we spend some energy here to try to ensure that we
2571 * either insert all file handles into the dictionary or none
2572 * at all. It's a little clumsy with the various popen modes
2573 * and variable number of files involved.
2574 */
2575 if (!_PyPopenProcs) {
2576 _PyPopenProcs = PyDict_New();
2577 }
2578
2579 if (_PyPopenProcs) {
2580 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2581 int ins_rc[3];
2582
2583 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2584 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2585
2586 procObj = PyList_New(2);
2587 hProcessObj = PyLong_FromVoidPtr(hProcess);
2588 intObj = PyInt_FromLong(file_count);
2589
2590 if (procObj && hProcessObj && intObj) {
2591 PyList_SetItem(procObj,0,hProcessObj);
2592 PyList_SetItem(procObj,1,intObj);
2593
2594 fileObj[0] = PyLong_FromVoidPtr(f1);
2595 if (fileObj[0]) {
2596 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2597 fileObj[0],
2598 procObj);
2599 }
2600 if (file_count >= 2) {
2601 fileObj[1] = PyLong_FromVoidPtr(f2);
2602 if (fileObj[1]) {
2603 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2604 fileObj[1],
2605 procObj);
2606 }
2607 }
2608 if (file_count >= 3) {
2609 fileObj[2] = PyLong_FromVoidPtr(f3);
2610 if (fileObj[2]) {
2611 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2612 fileObj[2],
2613 procObj);
2614 }
2615 }
2616
2617 if (ins_rc[0] < 0 || !fileObj[0] ||
2618 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2619 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2620 /* Something failed - remove any dictionary
2621 * entries that did make it.
2622 */
2623 if (!ins_rc[0] && fileObj[0]) {
2624 PyDict_DelItem(_PyPopenProcs,
2625 fileObj[0]);
2626 }
2627 if (!ins_rc[1] && fileObj[1]) {
2628 PyDict_DelItem(_PyPopenProcs,
2629 fileObj[1]);
2630 }
2631 if (!ins_rc[2] && fileObj[2]) {
2632 PyDict_DelItem(_PyPopenProcs,
2633 fileObj[2]);
2634 }
2635 }
2636 }
2637
2638 /*
2639 * Clean up our localized references for the dictionary keys
2640 * and value since PyDict_SetItem will Py_INCREF any copies
2641 * that got placed in the dictionary.
2642 */
2643 Py_XDECREF(procObj);
2644 Py_XDECREF(fileObj[0]);
2645 Py_XDECREF(fileObj[1]);
2646 Py_XDECREF(fileObj[2]);
2647 }
2648
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002649 /* Child is launched. Close the parents copy of those pipe
2650 * handles that only the child should have open. You need to
2651 * make sure that no handles to the write end of the output pipe
2652 * are maintained in this process or else the pipe will not close
2653 * when the child process exits and the ReadFile will hang. */
2654
2655 if (!CloseHandle(hChildStdinRd))
2656 return win32_error("CloseHandle", NULL);
2657
2658 if (!CloseHandle(hChildStdoutWr))
2659 return win32_error("CloseHandle", NULL);
2660
2661 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2662 return win32_error("CloseHandle", NULL);
2663
2664 return f;
2665}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002666
2667/*
2668 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2669 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002670 *
2671 * This function uses the _PyPopenProcs dictionary in order to map the
2672 * input file pointer to information about the process that was
2673 * originally created by the popen* call that created the file pointer.
2674 * The dictionary uses the file pointer as a key (with one entry
2675 * inserted for each file returned by the original popen* call) and a
2676 * single list object as the value for all files from a single call.
2677 * The list object contains the Win32 process handle at [0], and a file
2678 * count at [1], which is initialized to the total number of file
2679 * handles using that list.
2680 *
2681 * This function closes whichever handle it is passed, and decrements
2682 * the file count in the dictionary for the process handle pointed to
2683 * by this file. On the last close (when the file count reaches zero),
2684 * this function will wait for the child process and then return its
2685 * exit code as the result of the close() operation. This permits the
2686 * files to be closed in any order - it is always the close() of the
2687 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002688 */
Tim Peters736aa322000-09-01 06:51:24 +00002689
2690 /* RED_FLAG 31-Aug-2000 Tim
2691 * This is always called (today!) between a pair of
2692 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2693 * macros. So the thread running this has no valid thread state, as
2694 * far as Python is concerned. However, this calls some Python API
2695 * functions that cannot be called safely without a valid thread
2696 * state, in particular PyDict_GetItem.
2697 * As a temporary hack (although it may last for years ...), we
2698 * *rely* on not having a valid thread state in this function, in
2699 * order to create our own "from scratch".
2700 * This will deadlock if _PyPclose is ever called by a thread
2701 * holding the global lock.
2702 */
2703
Fredrik Lundh56055a42000-07-23 19:47:12 +00002704static int _PyPclose(FILE *file)
2705{
Fredrik Lundh20318932000-07-26 17:29:12 +00002706 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002707 DWORD exit_code;
2708 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002709 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2710 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002711#ifdef WITH_THREAD
2712 PyInterpreterState* pInterpreterState;
2713 PyThreadState* pThreadState;
2714#endif
2715
Fredrik Lundh20318932000-07-26 17:29:12 +00002716 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002717 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002718 */
2719 result = fclose(file);
2720
Tim Peters736aa322000-09-01 06:51:24 +00002721#ifdef WITH_THREAD
2722 /* Bootstrap a valid thread state into existence. */
2723 pInterpreterState = PyInterpreterState_New();
2724 if (!pInterpreterState) {
2725 /* Well, we're hosed now! We don't have a thread
2726 * state, so can't call a nice error routine, or raise
2727 * an exception. Just die.
2728 */
2729 Py_FatalError("unable to allocate interpreter state "
Tim Peters9acdd3a2000-09-01 19:26:36 +00002730 "when closing popen object.");
Tim Peters736aa322000-09-01 06:51:24 +00002731 return -1; /* unreachable */
2732 }
2733 pThreadState = PyThreadState_New(pInterpreterState);
2734 if (!pThreadState) {
2735 Py_FatalError("unable to allocate thread state "
Tim Peters9acdd3a2000-09-01 19:26:36 +00002736 "when closing popen object.");
Tim Peters736aa322000-09-01 06:51:24 +00002737 return -1; /* unreachable */
2738 }
2739 /* Grab the global lock. Note that this will deadlock if the
2740 * current thread already has the lock! (see RED_FLAG comments
2741 * before this function)
2742 */
2743 PyEval_RestoreThread(pThreadState);
2744#endif
2745
Fredrik Lundh56055a42000-07-23 19:47:12 +00002746 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002747 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2748 (procObj = PyDict_GetItem(_PyPopenProcs,
2749 fileObj)) != NULL &&
2750 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2751 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2752
2753 hProcess = PyLong_AsVoidPtr(hProcessObj);
2754 file_count = PyInt_AsLong(intObj);
2755
2756 if (file_count > 1) {
2757 /* Still other files referencing process */
2758 file_count--;
2759 PyList_SetItem(procObj,1,
2760 PyInt_FromLong(file_count));
2761 } else {
2762 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002763 if (result != EOF &&
2764 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2765 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002766 /* Possible truncation here in 16-bit environments, but
2767 * real exit codes are just the lower byte in any event.
2768 */
2769 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002770 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002771 /* Indicate failure - this will cause the file object
2772 * to raise an I/O error and translate the last Win32
2773 * error code from errno. We do have a problem with
2774 * last errors that overlap the normal errno table,
2775 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002776 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002777 if (result != EOF) {
2778 /* If the error wasn't from the fclose(), then
2779 * set errno for the file object error handling.
2780 */
2781 errno = GetLastError();
2782 }
2783 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002784 }
2785
2786 /* Free up the native handle at this point */
2787 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002788 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002789
Mark Hammondb37a3732000-08-14 04:47:33 +00002790 /* Remove this file pointer from dictionary */
2791 PyDict_DelItem(_PyPopenProcs, fileObj);
2792
2793 if (PyDict_Size(_PyPopenProcs) == 0) {
2794 Py_DECREF(_PyPopenProcs);
2795 _PyPopenProcs = NULL;
2796 }
2797
2798 } /* if object retrieval ok */
2799
2800 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002801 } /* if _PyPopenProcs */
2802
Tim Peters736aa322000-09-01 06:51:24 +00002803#ifdef WITH_THREAD
2804 /* Tear down the thread & interpreter states.
2805 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002806 * call the thread clear & delete functions, and indeed insist on
2807 * doing that themselves. The lock must be held during the clear, but
2808 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002809 */
2810 PyInterpreterState_Clear(pInterpreterState);
2811 PyEval_ReleaseThread(pThreadState);
2812 PyInterpreterState_Delete(pInterpreterState);
2813#endif
2814
Fredrik Lundh56055a42000-07-23 19:47:12 +00002815 return result;
2816}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002817
2818#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002819static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002820posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002821{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002822 char *name;
2823 char *mode = "r";
2824 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002825 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002826 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002827 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002828 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002829 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002830 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002831 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002832 if (fp == NULL)
2833 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002834 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002835 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002836 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002837 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002838}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002839#endif
2840
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002841#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002842
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002843
Guido van Rossumb6775db1994-08-01 11:34:53 +00002844#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002845static char posix_setuid__doc__[] =
2846"setuid(uid) -> None\n\
2847Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002849posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002850{
2851 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002852 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002853 return NULL;
2854 if (setuid(uid) < 0)
2855 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002856 Py_INCREF(Py_None);
2857 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002858}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002859#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002861
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002862#ifdef HAVE_SETEUID
2863static char posix_seteuid__doc__[] =
2864"seteuid(uid) -> None\n\
2865Set the current process's effective user id.";
2866static PyObject *
2867posix_seteuid (PyObject *self, PyObject *args)
2868{
2869 int euid;
2870 if (!PyArg_ParseTuple(args, "i", &euid)) {
2871 return NULL;
2872 } else if (seteuid(euid) < 0) {
2873 return posix_error();
2874 } else {
2875 Py_INCREF(Py_None);
2876 return Py_None;
2877 }
2878}
2879#endif /* HAVE_SETEUID */
2880
2881#ifdef HAVE_SETEGID
2882static char posix_setegid__doc__[] =
2883"setegid(gid) -> None\n\
2884Set the current process's effective group id.";
2885static PyObject *
2886posix_setegid (PyObject *self, PyObject *args)
2887{
2888 int egid;
2889 if (!PyArg_ParseTuple(args, "i", &egid)) {
2890 return NULL;
2891 } else if (setegid(egid) < 0) {
2892 return posix_error();
2893 } else {
2894 Py_INCREF(Py_None);
2895 return Py_None;
2896 }
2897}
2898#endif /* HAVE_SETEGID */
2899
2900#ifdef HAVE_SETREUID
2901static char posix_setreuid__doc__[] =
2902"seteuid(ruid, euid) -> None\n\
2903Set the current process's real and effective user ids.";
2904static PyObject *
2905posix_setreuid (PyObject *self, PyObject *args)
2906{
2907 int ruid, euid;
2908 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2909 return NULL;
2910 } else if (setreuid(ruid, euid) < 0) {
2911 return posix_error();
2912 } else {
2913 Py_INCREF(Py_None);
2914 return Py_None;
2915 }
2916}
2917#endif /* HAVE_SETREUID */
2918
2919#ifdef HAVE_SETREGID
2920static char posix_setregid__doc__[] =
2921"setegid(rgid, egid) -> None\n\
2922Set the current process's real and effective group ids.";
2923static PyObject *
2924posix_setregid (PyObject *self, PyObject *args)
2925{
2926 int rgid, egid;
2927 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2928 return NULL;
2929 } else if (setregid(rgid, egid) < 0) {
2930 return posix_error();
2931 } else {
2932 Py_INCREF(Py_None);
2933 return Py_None;
2934 }
2935}
2936#endif /* HAVE_SETREGID */
2937
Guido van Rossumb6775db1994-08-01 11:34:53 +00002938#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002939static char posix_setgid__doc__[] =
2940"setgid(gid) -> None\n\
2941Set the current process's group id.";
2942
Barry Warsaw53699e91996-12-10 23:23:01 +00002943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002944posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002945{
2946 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002947 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002948 return NULL;
2949 if (setgid(gid) < 0)
2950 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002951 Py_INCREF(Py_None);
2952 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002953}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002954#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002956
Guido van Rossumb6775db1994-08-01 11:34:53 +00002957#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002958static char posix_waitpid__doc__[] =
2959"waitpid(pid, options) -> (pid, status)\n\
2960Wait for completion of a give child process.";
2961
Barry Warsaw53699e91996-12-10 23:23:01 +00002962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002963posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002964{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002965 int pid, options;
2966#ifdef UNION_WAIT
2967 union wait status;
2968#define status_i (status.w_status)
2969#else
2970 int status;
2971#define status_i status
2972#endif
2973 status_i = 0;
2974
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002975 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002976 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002977 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002978#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002979 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002980#else
2981 pid = waitpid(pid, &status, options);
2982#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002983 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002984 if (pid == -1)
2985 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002986 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002987 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002988}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002989#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002990
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002991
Guido van Rossumad0ee831995-03-01 10:34:45 +00002992#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002993static char posix_wait__doc__[] =
2994"wait() -> (pid, status)\n\
2995Wait for completion of a child process.";
2996
Barry Warsaw53699e91996-12-10 23:23:01 +00002997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002998posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002999{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003000 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003001#ifdef UNION_WAIT
3002 union wait status;
3003#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003004#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003005 int status;
3006#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003007#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003008 if (!PyArg_ParseTuple(args, ":wait"))
3009 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003010 status_i = 0;
3011 Py_BEGIN_ALLOW_THREADS
3012 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003013 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003014 if (pid == -1)
3015 return posix_error();
3016 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003017 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003018#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003019}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003020#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003022
3023static char posix_lstat__doc__[] =
3024"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3025Like stat(path), but do not follow symbolic links.";
3026
Barry Warsaw53699e91996-12-10 23:23:01 +00003027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003028posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003029{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003030#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003031 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003032#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00003033 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003034#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003035}
3036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003037
Guido van Rossumb6775db1994-08-01 11:34:53 +00003038#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039static char posix_readlink__doc__[] =
3040"readlink(path) -> path\n\
3041Return a string representing the path to which the symbolic link points.";
3042
Barry Warsaw53699e91996-12-10 23:23:01 +00003043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003044posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003045{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003046 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003047 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003048 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003049 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003050 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003051 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003052 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003053 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003054 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003055 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003056 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003057}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003058#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003060
Guido van Rossumb6775db1994-08-01 11:34:53 +00003061#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003062static char posix_symlink__doc__[] =
3063"symlink(src, dst) -> None\n\
3064Create a symbolic link.";
3065
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003066static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003067posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003068{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003069 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003070}
3071#endif /* HAVE_SYMLINK */
3072
3073
3074#ifdef HAVE_TIMES
3075#ifndef HZ
3076#define HZ 60 /* Universal constant :-) */
3077#endif /* HZ */
3078
Guido van Rossumd48f2521997-12-05 22:19:34 +00003079#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3080static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003081system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003082{
3083 ULONG value = 0;
3084
3085 Py_BEGIN_ALLOW_THREADS
3086 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3087 Py_END_ALLOW_THREADS
3088
3089 return value;
3090}
3091
3092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003093posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003094{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003095 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003096 return NULL;
3097
3098 /* Currently Only Uptime is Provided -- Others Later */
3099 return Py_BuildValue("ddddd",
3100 (double)0 /* t.tms_utime / HZ */,
3101 (double)0 /* t.tms_stime / HZ */,
3102 (double)0 /* t.tms_cutime / HZ */,
3103 (double)0 /* t.tms_cstime / HZ */,
3104 (double)system_uptime() / 1000);
3105}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003106#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003108posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003109{
3110 struct tms t;
3111 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003112 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003113 return NULL;
3114 errno = 0;
3115 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003116 if (c == (clock_t) -1)
3117 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003118 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003119 (double)t.tms_utime / HZ,
3120 (double)t.tms_stime / HZ,
3121 (double)t.tms_cutime / HZ,
3122 (double)t.tms_cstime / HZ,
3123 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003124}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003125#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003126#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003127
3128
Guido van Rossum87755a21996-09-07 00:59:43 +00003129#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003130#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003131static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003132posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003133{
3134 FILETIME create, exit, kernel, user;
3135 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003136 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003137 return NULL;
3138 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003139 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3140 /* The fields of a FILETIME structure are the hi and lo part
3141 of a 64-bit value expressed in 100 nanosecond units.
3142 1e7 is one second in such units; 1e-7 the inverse.
3143 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3144 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003145 return Py_BuildValue(
3146 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003147 (double)(kernel.dwHighDateTime*429.4967296 +
3148 kernel.dwLowDateTime*1e-7),
3149 (double)(user.dwHighDateTime*429.4967296 +
3150 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003151 (double)0,
3152 (double)0,
3153 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003154}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003155#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003156
3157#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003158static char posix_times__doc__[] =
3159"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3160Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003161#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003163
Guido van Rossumb6775db1994-08-01 11:34:53 +00003164#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003165static char posix_setsid__doc__[] =
3166"setsid() -> None\n\
3167Call the system call setsid().";
3168
Barry Warsaw53699e91996-12-10 23:23:01 +00003169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003170posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003171{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003172 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003173 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003174 if (setsid() < 0)
3175 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003176 Py_INCREF(Py_None);
3177 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003178}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003179#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003180
Guido van Rossumb6775db1994-08-01 11:34:53 +00003181#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003182static char posix_setpgid__doc__[] =
3183"setpgid(pid, pgrp) -> None\n\
3184Call the system call setpgid().";
3185
Barry Warsaw53699e91996-12-10 23:23:01 +00003186static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003187posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003188{
3189 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003190 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003191 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003192 if (setpgid(pid, pgrp) < 0)
3193 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003194 Py_INCREF(Py_None);
3195 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003196}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003197#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003198
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003199
Guido van Rossumb6775db1994-08-01 11:34:53 +00003200#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003201static char posix_tcgetpgrp__doc__[] =
3202"tcgetpgrp(fd) -> pgid\n\
3203Return the process group associated with the terminal given by a fd.";
3204
Barry Warsaw53699e91996-12-10 23:23:01 +00003205static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003206posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003207{
3208 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003209 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003210 return NULL;
3211 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003212 if (pgid < 0)
3213 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003214 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003215}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003216#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003218
Guido van Rossumb6775db1994-08-01 11:34:53 +00003219#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003220static char posix_tcsetpgrp__doc__[] =
3221"tcsetpgrp(fd, pgid) -> None\n\
3222Set the process group associated with the terminal given by a fd.";
3223
Barry Warsaw53699e91996-12-10 23:23:01 +00003224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003225posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003226{
3227 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003228 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003229 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003230 if (tcsetpgrp(fd, pgid) < 0)
3231 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003232 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003233 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003234}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003235#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003236
Guido van Rossum687dd131993-05-17 08:34:16 +00003237/* Functions acting on file descriptors */
3238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003239static char posix_open__doc__[] =
3240"open(filename, flag [, mode=0777]) -> fd\n\
3241Open a file (for low level IO).";
3242
Barry Warsaw53699e91996-12-10 23:23:01 +00003243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003244posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003245{
3246 char *file;
3247 int flag;
3248 int mode = 0777;
3249 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003250 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3251 return NULL;
3252
Barry Warsaw53699e91996-12-10 23:23:01 +00003253 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003254 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003255 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003256 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003257 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003258 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003259}
3260
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003261
3262static char posix_close__doc__[] =
3263"close(fd) -> None\n\
3264Close a file descriptor (for low level IO).";
3265
Barry Warsaw53699e91996-12-10 23:23:01 +00003266static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003267posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003268{
3269 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003270 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003271 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003272 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003273 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003274 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003275 if (res < 0)
3276 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003277 Py_INCREF(Py_None);
3278 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003279}
3280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003281
3282static char posix_dup__doc__[] =
3283"dup(fd) -> fd2\n\
3284Return a duplicate of a file descriptor.";
3285
Barry Warsaw53699e91996-12-10 23:23:01 +00003286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003287posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003288{
3289 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003290 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003291 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003292 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003293 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003294 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003295 if (fd < 0)
3296 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003297 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003298}
3299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003300
3301static char posix_dup2__doc__[] =
3302"dup2(fd, fd2) -> None\n\
3303Duplicate file descriptor.";
3304
Barry Warsaw53699e91996-12-10 23:23:01 +00003305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003306posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003307{
3308 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003309 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003310 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003311 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003312 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003313 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003314 if (res < 0)
3315 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003316 Py_INCREF(Py_None);
3317 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003318}
3319
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003320
3321static char posix_lseek__doc__[] =
3322"lseek(fd, pos, how) -> newpos\n\
3323Set the current position of a file descriptor.";
3324
Barry Warsaw53699e91996-12-10 23:23:01 +00003325static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003326posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003327{
3328 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003329#ifdef MS_WIN64
3330 LONG_LONG pos, res;
3331#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003332 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003333#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003334 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003335 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003336 return NULL;
3337#ifdef SEEK_SET
3338 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3339 switch (how) {
3340 case 0: how = SEEK_SET; break;
3341 case 1: how = SEEK_CUR; break;
3342 case 2: how = SEEK_END; break;
3343 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003344#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003345
3346#if !defined(HAVE_LARGEFILE_SUPPORT)
3347 pos = PyInt_AsLong(posobj);
3348#else
3349 pos = PyLong_Check(posobj) ?
3350 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3351#endif
3352 if (PyErr_Occurred())
3353 return NULL;
3354
Barry Warsaw53699e91996-12-10 23:23:01 +00003355 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003356#ifdef MS_WIN64
3357 res = _lseeki64(fd, pos, how);
3358#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003359 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003360#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003361 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003362 if (res < 0)
3363 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003364
3365#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003366 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003367#else
3368 return PyLong_FromLongLong(res);
3369#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003370}
3371
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003372
3373static char posix_read__doc__[] =
3374"read(fd, buffersize) -> string\n\
3375Read a file descriptor.";
3376
Barry Warsaw53699e91996-12-10 23:23:01 +00003377static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003378posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003379{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003380 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003381 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003382 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003383 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003384 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003385 if (buffer == NULL)
3386 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003387 Py_BEGIN_ALLOW_THREADS
3388 n = read(fd, PyString_AsString(buffer), size);
3389 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003390 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003391 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003392 return posix_error();
3393 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003394 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003395 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003396 return buffer;
3397}
3398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003399
3400static char posix_write__doc__[] =
3401"write(fd, string) -> byteswritten\n\
3402Write a string to a file descriptor.";
3403
Barry Warsaw53699e91996-12-10 23:23:01 +00003404static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003405posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003406{
3407 int fd, size;
3408 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003409 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003410 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003411 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003412 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003413 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003414 if (size < 0)
3415 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003416 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003417}
3418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003419
3420static char posix_fstat__doc__[]=
3421"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3422Like stat(), but for an open file descriptor.";
3423
Barry Warsaw53699e91996-12-10 23:23:01 +00003424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003425posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003426{
3427 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003428 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003429 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003430 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003431 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003432 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003433 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003434 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003435 if (res != 0)
3436 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003437
3438 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003439}
3440
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003441
3442static char posix_fdopen__doc__[] =
3443"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3444Return an open file object connected to a file descriptor.";
3445
Barry Warsaw53699e91996-12-10 23:23:01 +00003446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003447posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003448{
Guido van Rossum687dd131993-05-17 08:34:16 +00003449 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003450 char *mode = "r";
3451 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003452 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003453 PyObject *f;
3454 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003455 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003456
Barry Warsaw53699e91996-12-10 23:23:01 +00003457 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003458 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003459 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003460 if (fp == NULL)
3461 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003462 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003463 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003464 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003465 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003466}
3467
Skip Montanaro1517d842000-07-19 14:34:14 +00003468static char posix_isatty__doc__[] =
3469"isatty(fd) -> Boolean\n\
3470Return true if the file descriptor 'fd' is an open file descriptor\n\
3471connected to a terminal.";
3472
3473static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003474posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003475{
3476 int fd;
3477 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3478 return NULL;
3479 return Py_BuildValue("i", isatty(fd));
3480}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003481
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003482#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003483static char posix_pipe__doc__[] =
3484"pipe() -> (read_end, write_end)\n\
3485Create a pipe.";
3486
Barry Warsaw53699e91996-12-10 23:23:01 +00003487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003488posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003489{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003490#if defined(PYOS_OS2)
3491 HFILE read, write;
3492 APIRET rc;
3493
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003494 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003495 return NULL;
3496
3497 Py_BEGIN_ALLOW_THREADS
3498 rc = DosCreatePipe( &read, &write, 4096);
3499 Py_END_ALLOW_THREADS
3500 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003501 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003502
3503 return Py_BuildValue("(ii)", read, write);
3504#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003505#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003506 int fds[2];
3507 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003508 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003509 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003510 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003511 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003512 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003513 if (res != 0)
3514 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003515 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003516#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003517 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003518 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003519 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003520 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003521 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003522 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003523 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003524 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003525 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003526 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003527 read_fd = _open_osfhandle((intptr_t)read, 0);
3528 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003529 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003530#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003531#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003532}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003533#endif /* HAVE_PIPE */
3534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003535
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003536#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003537static char posix_mkfifo__doc__[] =
3538"mkfifo(file, [, mode=0666]) -> None\n\
3539Create a FIFO (a POSIX named pipe).";
3540
Barry Warsaw53699e91996-12-10 23:23:01 +00003541static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003542posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003543{
3544 char *file;
3545 int mode = 0666;
3546 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003547 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003548 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003549 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003550 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003551 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003552 if (res < 0)
3553 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003554 Py_INCREF(Py_None);
3555 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003556}
3557#endif
3558
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003559
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003560#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003561static char posix_ftruncate__doc__[] =
3562"ftruncate(fd, length) -> None\n\
3563Truncate a file to a specified length.";
3564
Barry Warsaw53699e91996-12-10 23:23:01 +00003565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003566posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003567{
3568 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003569 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003570 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003571 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003572
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003573 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003574 return NULL;
3575
3576#if !defined(HAVE_LARGEFILE_SUPPORT)
3577 length = PyInt_AsLong(lenobj);
3578#else
3579 length = PyLong_Check(lenobj) ?
3580 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3581#endif
3582 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003583 return NULL;
3584
Barry Warsaw53699e91996-12-10 23:23:01 +00003585 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003586 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003587 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003588 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003589 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003590 return NULL;
3591 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003592 Py_INCREF(Py_None);
3593 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003594}
3595#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003596
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003597#ifdef NeXT
3598#define HAVE_PUTENV
3599/* Steve Spicklemire got this putenv from NeXTAnswers */
3600static int
3601putenv(char *newval)
3602{
3603 extern char **environ;
3604
3605 static int firstTime = 1;
3606 char **ep;
3607 char *cp;
3608 int esiz;
3609 char *np;
3610
3611 if (!(np = strchr(newval, '=')))
3612 return 1;
3613 *np = '\0';
3614
3615 /* look it up */
3616 for (ep=environ ; *ep ; ep++)
3617 {
3618 /* this should always be true... */
3619 if (cp = strchr(*ep, '='))
3620 {
3621 *cp = '\0';
3622 if (!strcmp(*ep, newval))
3623 {
3624 /* got it! */
3625 *cp = '=';
3626 break;
3627 }
3628 *cp = '=';
3629 }
3630 else
3631 {
3632 *np = '=';
3633 return 1;
3634 }
3635 }
3636
3637 *np = '=';
3638 if (*ep)
3639 {
3640 /* the string was already there:
3641 just replace it with the new one */
3642 *ep = newval;
3643 return 0;
3644 }
3645
3646 /* expand environ by one */
3647 for (esiz=2, ep=environ ; *ep ; ep++)
3648 esiz++;
3649 if (firstTime)
3650 {
3651 char **epp;
3652 char **newenv;
3653 if (!(newenv = malloc(esiz * sizeof(char *))))
3654 return 1;
3655
3656 for (ep=environ, epp=newenv ; *ep ;)
3657 *epp++ = *ep++;
3658 *epp++ = newval;
3659 *epp = (char *) 0;
3660 environ = newenv;
3661 }
3662 else
3663 {
3664 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3665 return 1;
3666 environ[esiz - 2] = newval;
3667 environ[esiz - 1] = (char *) 0;
3668 firstTime = 0;
3669 }
3670
3671 return 0;
3672}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003673#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003674
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003675
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003676#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003677static char posix_putenv__doc__[] =
3678"putenv(key, value) -> None\n\
3679Change or add an environment variable.";
3680
Fred Drake762e2061999-08-26 17:23:54 +00003681/* Save putenv() parameters as values here, so we can collect them when they
3682 * get re-set with another call for the same key. */
3683static PyObject *posix_putenv_garbage;
3684
Barry Warsaw53699e91996-12-10 23:23:01 +00003685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003686posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003687{
3688 char *s1, *s2;
3689 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003690 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003691
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003692 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003693 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003694
3695#if defined(PYOS_OS2)
3696 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3697 APIRET rc;
3698
3699 if (strlen(s2) == 0) /* If New Value is an Empty String */
3700 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3701
3702 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3703 if (rc != NO_ERROR)
3704 return os2_error(rc);
3705
3706 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3707 APIRET rc;
3708
3709 if (strlen(s2) == 0) /* If New Value is an Empty String */
3710 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3711
3712 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3713 if (rc != NO_ERROR)
3714 return os2_error(rc);
3715 } else {
3716#endif
3717
Fred Drake762e2061999-08-26 17:23:54 +00003718 /* XXX This can leak memory -- not easy to fix :-( */
3719 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3720 if (newstr == NULL)
3721 return PyErr_NoMemory();
3722 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003723 (void) sprintf(new, "%s=%s", s1, s2);
3724 if (putenv(new)) {
3725 posix_error();
3726 return NULL;
3727 }
Fred Drake762e2061999-08-26 17:23:54 +00003728 /* Install the first arg and newstr in posix_putenv_garbage;
3729 * this will cause previous value to be collected. This has to
3730 * happen after the real putenv() call because the old value
3731 * was still accessible until then. */
3732 if (PyDict_SetItem(posix_putenv_garbage,
3733 PyTuple_GET_ITEM(args, 0), newstr)) {
3734 /* really not much we can do; just leak */
3735 PyErr_Clear();
3736 }
3737 else {
3738 Py_DECREF(newstr);
3739 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003740
3741#if defined(PYOS_OS2)
3742 }
3743#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003744 Py_INCREF(Py_None);
3745 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003746}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003747#endif /* putenv */
3748
3749#ifdef HAVE_STRERROR
3750static char posix_strerror__doc__[] =
3751"strerror(code) -> string\n\
3752Translate an error code to a message string.";
3753
3754PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003755posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003756{
3757 int code;
3758 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003759 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003760 return NULL;
3761 message = strerror(code);
3762 if (message == NULL) {
3763 PyErr_SetString(PyExc_ValueError,
3764 "strerror code out of range");
3765 return NULL;
3766 }
3767 return PyString_FromString(message);
3768}
3769#endif /* strerror */
3770
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003771
Guido van Rossumc9641791998-08-04 15:26:23 +00003772#ifdef HAVE_SYS_WAIT_H
3773
3774#ifdef WIFSTOPPED
3775static char posix_WIFSTOPPED__doc__[] =
3776"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003777Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003778
3779static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003780posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003781{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003782#ifdef UNION_WAIT
3783 union wait status;
3784#define status_i (status.w_status)
3785#else
3786 int status;
3787#define status_i status
3788#endif
3789 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003790
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003791 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003792 {
3793 return NULL;
3794 }
3795
3796 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003797#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003798}
3799#endif /* WIFSTOPPED */
3800
3801#ifdef WIFSIGNALED
3802static char posix_WIFSIGNALED__doc__[] =
3803"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003804Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003805
3806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003807posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003808{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003809#ifdef UNION_WAIT
3810 union wait status;
3811#define status_i (status.w_status)
3812#else
3813 int status;
3814#define status_i status
3815#endif
3816 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003817
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003818 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003819 {
3820 return NULL;
3821 }
3822
3823 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003824#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003825}
3826#endif /* WIFSIGNALED */
3827
3828#ifdef WIFEXITED
3829static char posix_WIFEXITED__doc__[] =
3830"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003831Return true if the process returning 'status' exited using the exit()\n\
3832system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003833
3834static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003835posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003836{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003837#ifdef UNION_WAIT
3838 union wait status;
3839#define status_i (status.w_status)
3840#else
3841 int status;
3842#define status_i status
3843#endif
3844 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003845
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003846 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003847 {
3848 return NULL;
3849 }
3850
3851 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003852#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003853}
3854#endif /* WIFEXITED */
3855
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003856#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003857static char posix_WEXITSTATUS__doc__[] =
3858"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003859Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003860
3861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003862posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003863{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003864#ifdef UNION_WAIT
3865 union wait status;
3866#define status_i (status.w_status)
3867#else
3868 int status;
3869#define status_i status
3870#endif
3871 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003872
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003873 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003874 {
3875 return NULL;
3876 }
3877
3878 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003879#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003880}
3881#endif /* WEXITSTATUS */
3882
3883#ifdef WTERMSIG
3884static char posix_WTERMSIG__doc__[] =
3885"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003886Return the signal that terminated the process that provided the 'status'\n\
3887value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003888
3889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003890posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003891{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003892#ifdef UNION_WAIT
3893 union wait status;
3894#define status_i (status.w_status)
3895#else
3896 int status;
3897#define status_i status
3898#endif
3899 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003900
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003901 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003902 {
3903 return NULL;
3904 }
3905
3906 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003907#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003908}
3909#endif /* WTERMSIG */
3910
3911#ifdef WSTOPSIG
3912static char posix_WSTOPSIG__doc__[] =
3913"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003914Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003915
3916static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003917posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003918{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003919#ifdef UNION_WAIT
3920 union wait status;
3921#define status_i (status.w_status)
3922#else
3923 int status;
3924#define status_i status
3925#endif
3926 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003927
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003928 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003929 {
3930 return NULL;
3931 }
3932
3933 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003934#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003935}
3936#endif /* WSTOPSIG */
3937
3938#endif /* HAVE_SYS_WAIT_H */
3939
3940
Guido van Rossum94f6f721999-01-06 18:42:14 +00003941#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003942#ifdef _SCO_DS
3943/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3944 needed definitions in sys/statvfs.h */
3945#define _SVID3
3946#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003947#include <sys/statvfs.h>
3948
3949static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003950"fstatvfs(fd) -> \n\
3951 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003952Perform an fstatvfs system call on the given fd.";
3953
3954static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003955posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003956{
3957 int fd, res;
3958 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003959 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003960 return NULL;
3961 Py_BEGIN_ALLOW_THREADS
3962 res = fstatvfs(fd, &st);
3963 Py_END_ALLOW_THREADS
3964 if (res != 0)
3965 return posix_error();
3966#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003967 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003968 (long) st.f_bsize,
3969 (long) st.f_frsize,
3970 (long) st.f_blocks,
3971 (long) st.f_bfree,
3972 (long) st.f_bavail,
3973 (long) st.f_files,
3974 (long) st.f_ffree,
3975 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003976 (long) st.f_flag,
3977 (long) st.f_namemax);
3978#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003979 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003980 (long) st.f_bsize,
3981 (long) st.f_frsize,
3982 (LONG_LONG) st.f_blocks,
3983 (LONG_LONG) st.f_bfree,
3984 (LONG_LONG) st.f_bavail,
3985 (LONG_LONG) st.f_files,
3986 (LONG_LONG) st.f_ffree,
3987 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003988 (long) st.f_flag,
3989 (long) st.f_namemax);
3990#endif
3991}
3992#endif /* HAVE_FSTATVFS */
3993
3994
3995#if defined(HAVE_STATVFS)
3996#include <sys/statvfs.h>
3997
3998static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003999"statvfs(path) -> \n\
4000 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004001Perform a statvfs system call on the given path.";
4002
4003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004004posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004005{
4006 char *path;
4007 int res;
4008 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004009 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004010 return NULL;
4011 Py_BEGIN_ALLOW_THREADS
4012 res = statvfs(path, &st);
4013 Py_END_ALLOW_THREADS
4014 if (res != 0)
4015 return posix_error_with_filename(path);
4016#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004017 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004018 (long) st.f_bsize,
4019 (long) st.f_frsize,
4020 (long) st.f_blocks,
4021 (long) st.f_bfree,
4022 (long) st.f_bavail,
4023 (long) st.f_files,
4024 (long) st.f_ffree,
4025 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004026 (long) st.f_flag,
4027 (long) st.f_namemax);
4028#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004029 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004030 (long) st.f_bsize,
4031 (long) st.f_frsize,
4032 (LONG_LONG) st.f_blocks,
4033 (LONG_LONG) st.f_bfree,
4034 (LONG_LONG) st.f_bavail,
4035 (LONG_LONG) st.f_files,
4036 (LONG_LONG) st.f_ffree,
4037 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004038 (long) st.f_flag,
4039 (long) st.f_namemax);
4040#endif
4041}
4042#endif /* HAVE_STATVFS */
4043
4044
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004045#ifdef HAVE_TEMPNAM
4046static char posix_tempnam__doc__[] = "\
4047tempnam([dir[, prefix]]) -> string\n\
4048Return a unique name for a temporary file.\n\
4049The directory and a short may be specified as strings; they may be omitted\n\
4050or None if not needed.";
4051
4052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004053posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004054{
4055 PyObject *result = NULL;
4056 char *dir = NULL;
4057 char *pfx = NULL;
4058 char *name;
4059
4060 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4061 return NULL;
4062 name = tempnam(dir, pfx);
4063 if (name == NULL)
4064 return PyErr_NoMemory();
4065 result = PyString_FromString(name);
4066 free(name);
4067 return result;
4068}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004069#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004070
4071
4072#ifdef HAVE_TMPFILE
4073static char posix_tmpfile__doc__[] = "\
4074tmpfile() -> file object\n\
4075Create a temporary file with no directory entries.";
4076
4077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004078posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004079{
4080 FILE *fp;
4081
4082 if (!PyArg_ParseTuple(args, ":tmpfile"))
4083 return NULL;
4084 fp = tmpfile();
4085 if (fp == NULL)
4086 return posix_error();
4087 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4088}
4089#endif
4090
4091
4092#ifdef HAVE_TMPNAM
4093static char posix_tmpnam__doc__[] = "\
4094tmpnam() -> string\n\
4095Return a unique name for a temporary file.";
4096
4097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004098posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004099{
4100 char buffer[L_tmpnam];
4101 char *name;
4102
4103 if (!PyArg_ParseTuple(args, ":tmpnam"))
4104 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004105#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004106 name = tmpnam_r(buffer);
4107#else
4108 name = tmpnam(buffer);
4109#endif
4110 if (name == NULL) {
4111 PyErr_SetObject(PyExc_OSError,
4112 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004113#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004114 "unexpected NULL from tmpnam_r"
4115#else
4116 "unexpected NULL from tmpnam"
4117#endif
4118 ));
4119 return NULL;
4120 }
4121 return PyString_FromString(buffer);
4122}
4123#endif
4124
4125
Fred Drakec9680921999-12-13 16:37:25 +00004126/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4127 * It maps strings representing configuration variable names to
4128 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004129 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004130 * rarely-used constants. There are three separate tables that use
4131 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004132 *
4133 * This code is always included, even if none of the interfaces that
4134 * need it are included. The #if hackery needed to avoid it would be
4135 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004136 */
4137struct constdef {
4138 char *name;
4139 long value;
4140};
4141
Fred Drake12c6e2d1999-12-14 21:25:03 +00004142static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004143conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4144 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004145{
4146 if (PyInt_Check(arg)) {
4147 *valuep = PyInt_AS_LONG(arg);
4148 return 1;
4149 }
4150 if (PyString_Check(arg)) {
4151 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004152 size_t lo = 0;
4153 size_t mid;
4154 size_t hi = tablesize;
4155 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004156 char *confname = PyString_AS_STRING(arg);
4157 while (lo < hi) {
4158 mid = (lo + hi) / 2;
4159 cmp = strcmp(confname, table[mid].name);
4160 if (cmp < 0)
4161 hi = mid;
4162 else if (cmp > 0)
4163 lo = mid + 1;
4164 else {
4165 *valuep = table[mid].value;
4166 return 1;
4167 }
4168 }
4169 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4170 }
4171 else
4172 PyErr_SetString(PyExc_TypeError,
4173 "configuration names must be strings or integers");
4174 return 0;
4175}
4176
4177
4178#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4179static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004180#ifdef _PC_ABI_AIO_XFER_MAX
4181 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4182#endif
4183#ifdef _PC_ABI_ASYNC_IO
4184 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4185#endif
Fred Drakec9680921999-12-13 16:37:25 +00004186#ifdef _PC_ASYNC_IO
4187 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4188#endif
4189#ifdef _PC_CHOWN_RESTRICTED
4190 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4191#endif
4192#ifdef _PC_FILESIZEBITS
4193 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4194#endif
4195#ifdef _PC_LAST
4196 {"PC_LAST", _PC_LAST},
4197#endif
4198#ifdef _PC_LINK_MAX
4199 {"PC_LINK_MAX", _PC_LINK_MAX},
4200#endif
4201#ifdef _PC_MAX_CANON
4202 {"PC_MAX_CANON", _PC_MAX_CANON},
4203#endif
4204#ifdef _PC_MAX_INPUT
4205 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4206#endif
4207#ifdef _PC_NAME_MAX
4208 {"PC_NAME_MAX", _PC_NAME_MAX},
4209#endif
4210#ifdef _PC_NO_TRUNC
4211 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4212#endif
4213#ifdef _PC_PATH_MAX
4214 {"PC_PATH_MAX", _PC_PATH_MAX},
4215#endif
4216#ifdef _PC_PIPE_BUF
4217 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4218#endif
4219#ifdef _PC_PRIO_IO
4220 {"PC_PRIO_IO", _PC_PRIO_IO},
4221#endif
4222#ifdef _PC_SOCK_MAXBUF
4223 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4224#endif
4225#ifdef _PC_SYNC_IO
4226 {"PC_SYNC_IO", _PC_SYNC_IO},
4227#endif
4228#ifdef _PC_VDISABLE
4229 {"PC_VDISABLE", _PC_VDISABLE},
4230#endif
4231};
4232
Fred Drakec9680921999-12-13 16:37:25 +00004233static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004234conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004235{
4236 return conv_confname(arg, valuep, posix_constants_pathconf,
4237 sizeof(posix_constants_pathconf)
4238 / sizeof(struct constdef));
4239}
4240#endif
4241
4242#ifdef HAVE_FPATHCONF
4243static char posix_fpathconf__doc__[] = "\
4244fpathconf(fd, name) -> integer\n\
4245Return the configuration limit name for the file descriptor fd.\n\
4246If there is no limit, return -1.";
4247
4248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004249posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004250{
4251 PyObject *result = NULL;
4252 int name, fd;
4253
Fred Drake12c6e2d1999-12-14 21:25:03 +00004254 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4255 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004256 long limit;
4257
4258 errno = 0;
4259 limit = fpathconf(fd, name);
4260 if (limit == -1 && errno != 0)
4261 posix_error();
4262 else
4263 result = PyInt_FromLong(limit);
4264 }
4265 return result;
4266}
4267#endif
4268
4269
4270#ifdef HAVE_PATHCONF
4271static char posix_pathconf__doc__[] = "\
4272pathconf(path, name) -> integer\n\
4273Return the configuration limit name for the file or directory path.\n\
4274If there is no limit, return -1.";
4275
4276static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004277posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004278{
4279 PyObject *result = NULL;
4280 int name;
4281 char *path;
4282
4283 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4284 conv_path_confname, &name)) {
4285 long limit;
4286
4287 errno = 0;
4288 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004289 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004290 if (errno == EINVAL)
4291 /* could be a path or name problem */
4292 posix_error();
4293 else
4294 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004295 }
Fred Drakec9680921999-12-13 16:37:25 +00004296 else
4297 result = PyInt_FromLong(limit);
4298 }
4299 return result;
4300}
4301#endif
4302
4303#ifdef HAVE_CONFSTR
4304static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004305#ifdef _CS_ARCHITECTURE
4306 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4307#endif
4308#ifdef _CS_HOSTNAME
4309 {"CS_HOSTNAME", _CS_HOSTNAME},
4310#endif
4311#ifdef _CS_HW_PROVIDER
4312 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4313#endif
4314#ifdef _CS_HW_SERIAL
4315 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4316#endif
4317#ifdef _CS_INITTAB_NAME
4318 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4319#endif
Fred Drakec9680921999-12-13 16:37:25 +00004320#ifdef _CS_LFS64_CFLAGS
4321 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4322#endif
4323#ifdef _CS_LFS64_LDFLAGS
4324 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4325#endif
4326#ifdef _CS_LFS64_LIBS
4327 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4328#endif
4329#ifdef _CS_LFS64_LINTFLAGS
4330 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4331#endif
4332#ifdef _CS_LFS_CFLAGS
4333 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4334#endif
4335#ifdef _CS_LFS_LDFLAGS
4336 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4337#endif
4338#ifdef _CS_LFS_LIBS
4339 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4340#endif
4341#ifdef _CS_LFS_LINTFLAGS
4342 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4343#endif
Fred Draked86ed291999-12-15 15:34:33 +00004344#ifdef _CS_MACHINE
4345 {"CS_MACHINE", _CS_MACHINE},
4346#endif
Fred Drakec9680921999-12-13 16:37:25 +00004347#ifdef _CS_PATH
4348 {"CS_PATH", _CS_PATH},
4349#endif
Fred Draked86ed291999-12-15 15:34:33 +00004350#ifdef _CS_RELEASE
4351 {"CS_RELEASE", _CS_RELEASE},
4352#endif
4353#ifdef _CS_SRPC_DOMAIN
4354 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4355#endif
4356#ifdef _CS_SYSNAME
4357 {"CS_SYSNAME", _CS_SYSNAME},
4358#endif
4359#ifdef _CS_VERSION
4360 {"CS_VERSION", _CS_VERSION},
4361#endif
Fred Drakec9680921999-12-13 16:37:25 +00004362#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4363 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4364#endif
4365#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4366 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4367#endif
4368#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4369 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4370#endif
4371#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4372 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4373#endif
4374#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4375 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4376#endif
4377#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4378 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4379#endif
4380#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4381 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4382#endif
4383#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4384 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4385#endif
4386#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4387 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4388#endif
4389#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4390 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4391#endif
4392#ifdef _CS_XBS5_LP64_OFF64_LIBS
4393 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4394#endif
4395#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4396 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4397#endif
4398#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4399 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4400#endif
4401#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4402 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4403#endif
4404#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4405 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4406#endif
4407#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4408 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4409#endif
Fred Draked86ed291999-12-15 15:34:33 +00004410#ifdef _MIPS_CS_AVAIL_PROCESSORS
4411 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4412#endif
4413#ifdef _MIPS_CS_BASE
4414 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4415#endif
4416#ifdef _MIPS_CS_HOSTID
4417 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4418#endif
4419#ifdef _MIPS_CS_HW_NAME
4420 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4421#endif
4422#ifdef _MIPS_CS_NUM_PROCESSORS
4423 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4424#endif
4425#ifdef _MIPS_CS_OSREL_MAJ
4426 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4427#endif
4428#ifdef _MIPS_CS_OSREL_MIN
4429 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4430#endif
4431#ifdef _MIPS_CS_OSREL_PATCH
4432 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4433#endif
4434#ifdef _MIPS_CS_OS_NAME
4435 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4436#endif
4437#ifdef _MIPS_CS_OS_PROVIDER
4438 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4439#endif
4440#ifdef _MIPS_CS_PROCESSORS
4441 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4442#endif
4443#ifdef _MIPS_CS_SERIAL
4444 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4445#endif
4446#ifdef _MIPS_CS_VENDOR
4447 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4448#endif
Fred Drakec9680921999-12-13 16:37:25 +00004449};
4450
4451static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004452conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004453{
4454 return conv_confname(arg, valuep, posix_constants_confstr,
4455 sizeof(posix_constants_confstr)
4456 / sizeof(struct constdef));
4457}
4458
4459static char posix_confstr__doc__[] = "\
4460confstr(name) -> string\n\
4461Return a string-valued system configuration variable.";
4462
4463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004464posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004465{
4466 PyObject *result = NULL;
4467 int name;
4468 char buffer[64];
4469
4470 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4471 int len = confstr(name, buffer, sizeof(buffer));
4472
Fred Drakec9680921999-12-13 16:37:25 +00004473 errno = 0;
4474 if (len == 0) {
4475 if (errno != 0)
4476 posix_error();
4477 else
4478 result = PyString_FromString("");
4479 }
4480 else {
4481 if (len >= sizeof(buffer)) {
4482 result = PyString_FromStringAndSize(NULL, len);
4483 if (result != NULL)
4484 confstr(name, PyString_AS_STRING(result), len+1);
4485 }
4486 else
4487 result = PyString_FromString(buffer);
4488 }
4489 }
4490 return result;
4491}
4492#endif
4493
4494
4495#ifdef HAVE_SYSCONF
4496static struct constdef posix_constants_sysconf[] = {
4497#ifdef _SC_2_CHAR_TERM
4498 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4499#endif
4500#ifdef _SC_2_C_BIND
4501 {"SC_2_C_BIND", _SC_2_C_BIND},
4502#endif
4503#ifdef _SC_2_C_DEV
4504 {"SC_2_C_DEV", _SC_2_C_DEV},
4505#endif
4506#ifdef _SC_2_C_VERSION
4507 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4508#endif
4509#ifdef _SC_2_FORT_DEV
4510 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4511#endif
4512#ifdef _SC_2_FORT_RUN
4513 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4514#endif
4515#ifdef _SC_2_LOCALEDEF
4516 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4517#endif
4518#ifdef _SC_2_SW_DEV
4519 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4520#endif
4521#ifdef _SC_2_UPE
4522 {"SC_2_UPE", _SC_2_UPE},
4523#endif
4524#ifdef _SC_2_VERSION
4525 {"SC_2_VERSION", _SC_2_VERSION},
4526#endif
Fred Draked86ed291999-12-15 15:34:33 +00004527#ifdef _SC_ABI_ASYNCHRONOUS_IO
4528 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4529#endif
4530#ifdef _SC_ACL
4531 {"SC_ACL", _SC_ACL},
4532#endif
Fred Drakec9680921999-12-13 16:37:25 +00004533#ifdef _SC_AIO_LISTIO_MAX
4534 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4535#endif
Fred Drakec9680921999-12-13 16:37:25 +00004536#ifdef _SC_AIO_MAX
4537 {"SC_AIO_MAX", _SC_AIO_MAX},
4538#endif
4539#ifdef _SC_AIO_PRIO_DELTA_MAX
4540 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4541#endif
4542#ifdef _SC_ARG_MAX
4543 {"SC_ARG_MAX", _SC_ARG_MAX},
4544#endif
4545#ifdef _SC_ASYNCHRONOUS_IO
4546 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4547#endif
4548#ifdef _SC_ATEXIT_MAX
4549 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4550#endif
Fred Draked86ed291999-12-15 15:34:33 +00004551#ifdef _SC_AUDIT
4552 {"SC_AUDIT", _SC_AUDIT},
4553#endif
Fred Drakec9680921999-12-13 16:37:25 +00004554#ifdef _SC_AVPHYS_PAGES
4555 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4556#endif
4557#ifdef _SC_BC_BASE_MAX
4558 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4559#endif
4560#ifdef _SC_BC_DIM_MAX
4561 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4562#endif
4563#ifdef _SC_BC_SCALE_MAX
4564 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4565#endif
4566#ifdef _SC_BC_STRING_MAX
4567 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4568#endif
Fred Draked86ed291999-12-15 15:34:33 +00004569#ifdef _SC_CAP
4570 {"SC_CAP", _SC_CAP},
4571#endif
Fred Drakec9680921999-12-13 16:37:25 +00004572#ifdef _SC_CHARCLASS_NAME_MAX
4573 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4574#endif
4575#ifdef _SC_CHAR_BIT
4576 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4577#endif
4578#ifdef _SC_CHAR_MAX
4579 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4580#endif
4581#ifdef _SC_CHAR_MIN
4582 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4583#endif
4584#ifdef _SC_CHILD_MAX
4585 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4586#endif
4587#ifdef _SC_CLK_TCK
4588 {"SC_CLK_TCK", _SC_CLK_TCK},
4589#endif
4590#ifdef _SC_COHER_BLKSZ
4591 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4592#endif
4593#ifdef _SC_COLL_WEIGHTS_MAX
4594 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4595#endif
4596#ifdef _SC_DCACHE_ASSOC
4597 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4598#endif
4599#ifdef _SC_DCACHE_BLKSZ
4600 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4601#endif
4602#ifdef _SC_DCACHE_LINESZ
4603 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4604#endif
4605#ifdef _SC_DCACHE_SZ
4606 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4607#endif
4608#ifdef _SC_DCACHE_TBLKSZ
4609 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4610#endif
4611#ifdef _SC_DELAYTIMER_MAX
4612 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4613#endif
4614#ifdef _SC_EQUIV_CLASS_MAX
4615 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4616#endif
4617#ifdef _SC_EXPR_NEST_MAX
4618 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4619#endif
4620#ifdef _SC_FSYNC
4621 {"SC_FSYNC", _SC_FSYNC},
4622#endif
4623#ifdef _SC_GETGR_R_SIZE_MAX
4624 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4625#endif
4626#ifdef _SC_GETPW_R_SIZE_MAX
4627 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4628#endif
4629#ifdef _SC_ICACHE_ASSOC
4630 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4631#endif
4632#ifdef _SC_ICACHE_BLKSZ
4633 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4634#endif
4635#ifdef _SC_ICACHE_LINESZ
4636 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4637#endif
4638#ifdef _SC_ICACHE_SZ
4639 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4640#endif
Fred Draked86ed291999-12-15 15:34:33 +00004641#ifdef _SC_INF
4642 {"SC_INF", _SC_INF},
4643#endif
Fred Drakec9680921999-12-13 16:37:25 +00004644#ifdef _SC_INT_MAX
4645 {"SC_INT_MAX", _SC_INT_MAX},
4646#endif
4647#ifdef _SC_INT_MIN
4648 {"SC_INT_MIN", _SC_INT_MIN},
4649#endif
4650#ifdef _SC_IOV_MAX
4651 {"SC_IOV_MAX", _SC_IOV_MAX},
4652#endif
Fred Draked86ed291999-12-15 15:34:33 +00004653#ifdef _SC_IP_SECOPTS
4654 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4655#endif
Fred Drakec9680921999-12-13 16:37:25 +00004656#ifdef _SC_JOB_CONTROL
4657 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4658#endif
Fred Draked86ed291999-12-15 15:34:33 +00004659#ifdef _SC_KERN_POINTERS
4660 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4661#endif
4662#ifdef _SC_KERN_SIM
4663 {"SC_KERN_SIM", _SC_KERN_SIM},
4664#endif
Fred Drakec9680921999-12-13 16:37:25 +00004665#ifdef _SC_LINE_MAX
4666 {"SC_LINE_MAX", _SC_LINE_MAX},
4667#endif
4668#ifdef _SC_LOGIN_NAME_MAX
4669 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4670#endif
4671#ifdef _SC_LOGNAME_MAX
4672 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4673#endif
4674#ifdef _SC_LONG_BIT
4675 {"SC_LONG_BIT", _SC_LONG_BIT},
4676#endif
Fred Draked86ed291999-12-15 15:34:33 +00004677#ifdef _SC_MAC
4678 {"SC_MAC", _SC_MAC},
4679#endif
Fred Drakec9680921999-12-13 16:37:25 +00004680#ifdef _SC_MAPPED_FILES
4681 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4682#endif
4683#ifdef _SC_MAXPID
4684 {"SC_MAXPID", _SC_MAXPID},
4685#endif
4686#ifdef _SC_MB_LEN_MAX
4687 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4688#endif
4689#ifdef _SC_MEMLOCK
4690 {"SC_MEMLOCK", _SC_MEMLOCK},
4691#endif
4692#ifdef _SC_MEMLOCK_RANGE
4693 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4694#endif
4695#ifdef _SC_MEMORY_PROTECTION
4696 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4697#endif
4698#ifdef _SC_MESSAGE_PASSING
4699 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4700#endif
Fred Draked86ed291999-12-15 15:34:33 +00004701#ifdef _SC_MMAP_FIXED_ALIGNMENT
4702 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4703#endif
Fred Drakec9680921999-12-13 16:37:25 +00004704#ifdef _SC_MQ_OPEN_MAX
4705 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4706#endif
4707#ifdef _SC_MQ_PRIO_MAX
4708 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4709#endif
Fred Draked86ed291999-12-15 15:34:33 +00004710#ifdef _SC_NACLS_MAX
4711 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4712#endif
Fred Drakec9680921999-12-13 16:37:25 +00004713#ifdef _SC_NGROUPS_MAX
4714 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4715#endif
4716#ifdef _SC_NL_ARGMAX
4717 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4718#endif
4719#ifdef _SC_NL_LANGMAX
4720 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4721#endif
4722#ifdef _SC_NL_MSGMAX
4723 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4724#endif
4725#ifdef _SC_NL_NMAX
4726 {"SC_NL_NMAX", _SC_NL_NMAX},
4727#endif
4728#ifdef _SC_NL_SETMAX
4729 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4730#endif
4731#ifdef _SC_NL_TEXTMAX
4732 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4733#endif
4734#ifdef _SC_NPROCESSORS_CONF
4735 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4736#endif
4737#ifdef _SC_NPROCESSORS_ONLN
4738 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4739#endif
Fred Draked86ed291999-12-15 15:34:33 +00004740#ifdef _SC_NPROC_CONF
4741 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4742#endif
4743#ifdef _SC_NPROC_ONLN
4744 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4745#endif
Fred Drakec9680921999-12-13 16:37:25 +00004746#ifdef _SC_NZERO
4747 {"SC_NZERO", _SC_NZERO},
4748#endif
4749#ifdef _SC_OPEN_MAX
4750 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4751#endif
4752#ifdef _SC_PAGESIZE
4753 {"SC_PAGESIZE", _SC_PAGESIZE},
4754#endif
4755#ifdef _SC_PAGE_SIZE
4756 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4757#endif
4758#ifdef _SC_PASS_MAX
4759 {"SC_PASS_MAX", _SC_PASS_MAX},
4760#endif
4761#ifdef _SC_PHYS_PAGES
4762 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4763#endif
4764#ifdef _SC_PII
4765 {"SC_PII", _SC_PII},
4766#endif
4767#ifdef _SC_PII_INTERNET
4768 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4769#endif
4770#ifdef _SC_PII_INTERNET_DGRAM
4771 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4772#endif
4773#ifdef _SC_PII_INTERNET_STREAM
4774 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4775#endif
4776#ifdef _SC_PII_OSI
4777 {"SC_PII_OSI", _SC_PII_OSI},
4778#endif
4779#ifdef _SC_PII_OSI_CLTS
4780 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4781#endif
4782#ifdef _SC_PII_OSI_COTS
4783 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4784#endif
4785#ifdef _SC_PII_OSI_M
4786 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4787#endif
4788#ifdef _SC_PII_SOCKET
4789 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4790#endif
4791#ifdef _SC_PII_XTI
4792 {"SC_PII_XTI", _SC_PII_XTI},
4793#endif
4794#ifdef _SC_POLL
4795 {"SC_POLL", _SC_POLL},
4796#endif
4797#ifdef _SC_PRIORITIZED_IO
4798 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4799#endif
4800#ifdef _SC_PRIORITY_SCHEDULING
4801 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4802#endif
4803#ifdef _SC_REALTIME_SIGNALS
4804 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4805#endif
4806#ifdef _SC_RE_DUP_MAX
4807 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4808#endif
4809#ifdef _SC_RTSIG_MAX
4810 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4811#endif
4812#ifdef _SC_SAVED_IDS
4813 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4814#endif
4815#ifdef _SC_SCHAR_MAX
4816 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4817#endif
4818#ifdef _SC_SCHAR_MIN
4819 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4820#endif
4821#ifdef _SC_SELECT
4822 {"SC_SELECT", _SC_SELECT},
4823#endif
4824#ifdef _SC_SEMAPHORES
4825 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4826#endif
4827#ifdef _SC_SEM_NSEMS_MAX
4828 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4829#endif
4830#ifdef _SC_SEM_VALUE_MAX
4831 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4832#endif
4833#ifdef _SC_SHARED_MEMORY_OBJECTS
4834 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4835#endif
4836#ifdef _SC_SHRT_MAX
4837 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4838#endif
4839#ifdef _SC_SHRT_MIN
4840 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4841#endif
4842#ifdef _SC_SIGQUEUE_MAX
4843 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4844#endif
4845#ifdef _SC_SIGRT_MAX
4846 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4847#endif
4848#ifdef _SC_SIGRT_MIN
4849 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4850#endif
Fred Draked86ed291999-12-15 15:34:33 +00004851#ifdef _SC_SOFTPOWER
4852 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4853#endif
Fred Drakec9680921999-12-13 16:37:25 +00004854#ifdef _SC_SPLIT_CACHE
4855 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4856#endif
4857#ifdef _SC_SSIZE_MAX
4858 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4859#endif
4860#ifdef _SC_STACK_PROT
4861 {"SC_STACK_PROT", _SC_STACK_PROT},
4862#endif
4863#ifdef _SC_STREAM_MAX
4864 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4865#endif
4866#ifdef _SC_SYNCHRONIZED_IO
4867 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4868#endif
4869#ifdef _SC_THREADS
4870 {"SC_THREADS", _SC_THREADS},
4871#endif
4872#ifdef _SC_THREAD_ATTR_STACKADDR
4873 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4874#endif
4875#ifdef _SC_THREAD_ATTR_STACKSIZE
4876 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4877#endif
4878#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4879 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4880#endif
4881#ifdef _SC_THREAD_KEYS_MAX
4882 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4883#endif
4884#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4885 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4886#endif
4887#ifdef _SC_THREAD_PRIO_INHERIT
4888 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4889#endif
4890#ifdef _SC_THREAD_PRIO_PROTECT
4891 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4892#endif
4893#ifdef _SC_THREAD_PROCESS_SHARED
4894 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4895#endif
4896#ifdef _SC_THREAD_SAFE_FUNCTIONS
4897 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4898#endif
4899#ifdef _SC_THREAD_STACK_MIN
4900 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4901#endif
4902#ifdef _SC_THREAD_THREADS_MAX
4903 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4904#endif
4905#ifdef _SC_TIMERS
4906 {"SC_TIMERS", _SC_TIMERS},
4907#endif
4908#ifdef _SC_TIMER_MAX
4909 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4910#endif
4911#ifdef _SC_TTY_NAME_MAX
4912 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4913#endif
4914#ifdef _SC_TZNAME_MAX
4915 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4916#endif
4917#ifdef _SC_T_IOV_MAX
4918 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4919#endif
4920#ifdef _SC_UCHAR_MAX
4921 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4922#endif
4923#ifdef _SC_UINT_MAX
4924 {"SC_UINT_MAX", _SC_UINT_MAX},
4925#endif
4926#ifdef _SC_UIO_MAXIOV
4927 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4928#endif
4929#ifdef _SC_ULONG_MAX
4930 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4931#endif
4932#ifdef _SC_USHRT_MAX
4933 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4934#endif
4935#ifdef _SC_VERSION
4936 {"SC_VERSION", _SC_VERSION},
4937#endif
4938#ifdef _SC_WORD_BIT
4939 {"SC_WORD_BIT", _SC_WORD_BIT},
4940#endif
4941#ifdef _SC_XBS5_ILP32_OFF32
4942 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4943#endif
4944#ifdef _SC_XBS5_ILP32_OFFBIG
4945 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4946#endif
4947#ifdef _SC_XBS5_LP64_OFF64
4948 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4949#endif
4950#ifdef _SC_XBS5_LPBIG_OFFBIG
4951 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4952#endif
4953#ifdef _SC_XOPEN_CRYPT
4954 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4955#endif
4956#ifdef _SC_XOPEN_ENH_I18N
4957 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4958#endif
4959#ifdef _SC_XOPEN_LEGACY
4960 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4961#endif
4962#ifdef _SC_XOPEN_REALTIME
4963 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4964#endif
4965#ifdef _SC_XOPEN_REALTIME_THREADS
4966 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4967#endif
4968#ifdef _SC_XOPEN_SHM
4969 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4970#endif
4971#ifdef _SC_XOPEN_UNIX
4972 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4973#endif
4974#ifdef _SC_XOPEN_VERSION
4975 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4976#endif
4977#ifdef _SC_XOPEN_XCU_VERSION
4978 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4979#endif
4980#ifdef _SC_XOPEN_XPG2
4981 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4982#endif
4983#ifdef _SC_XOPEN_XPG3
4984 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4985#endif
4986#ifdef _SC_XOPEN_XPG4
4987 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4988#endif
4989};
4990
4991static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004992conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004993{
4994 return conv_confname(arg, valuep, posix_constants_sysconf,
4995 sizeof(posix_constants_sysconf)
4996 / sizeof(struct constdef));
4997}
4998
4999static char posix_sysconf__doc__[] = "\
5000sysconf(name) -> integer\n\
5001Return an integer-valued system configuration variable.";
5002
5003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005004posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005005{
5006 PyObject *result = NULL;
5007 int name;
5008
5009 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5010 int value;
5011
5012 errno = 0;
5013 value = sysconf(name);
5014 if (value == -1 && errno != 0)
5015 posix_error();
5016 else
5017 result = PyInt_FromLong(value);
5018 }
5019 return result;
5020}
5021#endif
5022
5023
Fred Drakebec628d1999-12-15 18:31:10 +00005024/* This code is used to ensure that the tables of configuration value names
5025 * are in sorted order as required by conv_confname(), and also to build the
5026 * the exported dictionaries that are used to publish information about the
5027 * names available on the host platform.
5028 *
5029 * Sorting the table at runtime ensures that the table is properly ordered
5030 * when used, even for platforms we're not able to test on. It also makes
5031 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005032 */
Fred Drakebec628d1999-12-15 18:31:10 +00005033
5034static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005035cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005036{
5037 const struct constdef *c1 =
5038 (const struct constdef *) v1;
5039 const struct constdef *c2 =
5040 (const struct constdef *) v2;
5041
5042 return strcmp(c1->name, c2->name);
5043}
5044
5045static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005046setup_confname_table(struct constdef *table, size_t tablesize,
5047 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005048{
Fred Drakebec628d1999-12-15 18:31:10 +00005049 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005050 size_t i;
5051 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005052
5053 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5054 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005055 if (d == NULL)
5056 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005057
Barry Warsaw3155db32000-04-13 15:20:40 +00005058 for (i=0; i < tablesize; ++i) {
5059 PyObject *o = PyInt_FromLong(table[i].value);
5060 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5061 Py_XDECREF(o);
5062 Py_DECREF(d);
5063 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005064 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005065 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005066 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005067 status = PyDict_SetItemString(moddict, tablename, d);
5068 Py_DECREF(d);
5069 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005070}
5071
Fred Drakebec628d1999-12-15 18:31:10 +00005072/* Return -1 on failure, 0 on success. */
5073static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005074setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005075{
5076#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005077 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005078 sizeof(posix_constants_pathconf)
5079 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005080 "pathconf_names", moddict))
5081 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005082#endif
5083#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005084 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005085 sizeof(posix_constants_confstr)
5086 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005087 "confstr_names", moddict))
5088 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005089#endif
5090#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005091 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005092 sizeof(posix_constants_sysconf)
5093 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005094 "sysconf_names", moddict))
5095 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005096#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005097 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005098}
Fred Draked86ed291999-12-15 15:34:33 +00005099
5100
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005101static char posix_abort__doc__[] = "\
5102abort() -> does not return!\n\
5103Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5104in the hardest way possible on the hosting operating system.";
5105
5106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005107posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005108{
5109 if (!PyArg_ParseTuple(args, ":abort"))
5110 return NULL;
5111 abort();
5112 /*NOTREACHED*/
5113 Py_FatalError("abort() called from Python code didn't abort!");
5114 return NULL;
5115}
Fred Drakebec628d1999-12-15 18:31:10 +00005116
Tim Petersf58a7aa2000-09-22 10:05:54 +00005117#ifdef MS_WIN32
5118static char win32_startfile__doc__[] = "\
5119startfile(filepath) - Start a file with its associated application.\n\
5120\n\
5121This acts like double-clicking the file in Explorer, or giving the file\n\
5122name as an argument to the DOS \"start\" command: the file is opened\n\
5123with whatever application (if any) its extension is associated.\n\
5124\n\
5125startfile returns as soon as the associated application is launched.\n\
5126There is no option to wait for the application to close, and no way\n\
5127to retrieve the application's exit status.\n\
5128\n\
5129The filepath is relative to the current directory. If you want to use\n\
5130an absolute path, make sure the first character is not a slash (\"/\");\n\
5131the underlying Win32 ShellExecute function doesn't work if it is.";
5132
5133static PyObject *
5134win32_startfile(PyObject *self, PyObject *args)
5135{
5136 char *filepath;
5137 HINSTANCE rc;
5138 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5139 return NULL;
5140 Py_BEGIN_ALLOW_THREADS
5141 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5142 Py_END_ALLOW_THREADS
5143 if (rc <= (HINSTANCE)32)
5144 return win32_error("startfile", filepath);
5145 Py_INCREF(Py_None);
5146 return Py_None;
5147}
5148#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005149
5150static PyMethodDef posix_methods[] = {
5151 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5152#ifdef HAVE_TTYNAME
5153 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5154#endif
5155 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5156 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005157#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005158 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005159#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005160#ifdef HAVE_CTERMID
5161 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5162#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005163#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005164 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005165#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005166#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005167 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005168#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005169 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5170 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5171 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005172#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005173 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005174#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005175#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005176 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005177#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005178 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5179 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5180 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005181#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005182 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005183#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005184#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005185 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005186#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005187 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005188#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005189 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005190#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005191 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5192 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5193 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005194#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005195 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005196#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005197 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005198#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005199 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5200 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005201#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005202#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005203 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5204 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005205#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005206#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005207 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005208#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005209#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005210 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005211#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005212#ifdef HAVE_FORKPTY
5213 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5214#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005215#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005216 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005217#endif /* HAVE_GETEGID */
5218#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005219 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005220#endif /* HAVE_GETEUID */
5221#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005222 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005223#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005224#ifdef HAVE_GETGROUPS
5225 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5226#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005227 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005228#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005229 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005230#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005231#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005232 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005233#endif /* HAVE_GETPPID */
5234#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005235 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005236#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005237#ifdef HAVE_GETLOGIN
5238 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5239#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005240#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005241 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005242#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005243#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005244 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005245#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005246#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005247 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005248#ifdef MS_WIN32
5249 {"popen2", win32_popen2, METH_VARARGS},
5250 {"popen3", win32_popen3, METH_VARARGS},
5251 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005252 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005253#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005254#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005255#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005256 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005257#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005258#ifdef HAVE_SETEUID
5259 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5260#endif /* HAVE_SETEUID */
5261#ifdef HAVE_SETEGID
5262 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5263#endif /* HAVE_SETEGID */
5264#ifdef HAVE_SETREUID
5265 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5266#endif /* HAVE_SETREUID */
5267#ifdef HAVE_SETREGID
5268 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5269#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005270#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005271 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005272#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005273#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005274 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005275#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005276#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005277 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005278#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005279#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005280 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005281#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005282#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005283 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005284#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005285#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005286 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005287#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005288#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005289 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005290#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005291#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005292 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005293#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005294 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5295 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5296 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5297 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5298 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5299 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5300 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5301 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5302 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005303 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005304#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005305 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005306#endif
5307#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005308 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005309#endif
5310#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005311 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005312#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005313#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005314 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005315#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005316#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005317 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005318#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005319#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005320 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005321#endif
5322#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005323 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005324#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005325#ifdef HAVE_SYS_WAIT_H
5326#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005327 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005328#endif /* WIFSTOPPED */
5329#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005330 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005331#endif /* WIFSIGNALED */
5332#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005333 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005334#endif /* WIFEXITED */
5335#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005336 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005337#endif /* WEXITSTATUS */
5338#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005339 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005340#endif /* WTERMSIG */
5341#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005342 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005343#endif /* WSTOPSIG */
5344#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005345#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005346 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005347#endif
5348#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005349 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005350#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005351#ifdef HAVE_TMPNAM
5352 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5353#endif
5354#ifdef HAVE_TEMPNAM
5355 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5356#endif
5357#ifdef HAVE_TMPNAM
5358 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5359#endif
Fred Drakec9680921999-12-13 16:37:25 +00005360#ifdef HAVE_CONFSTR
5361 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5362#endif
5363#ifdef HAVE_SYSCONF
5364 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5365#endif
5366#ifdef HAVE_FPATHCONF
5367 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5368#endif
5369#ifdef HAVE_PATHCONF
5370 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5371#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005372 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005373 {NULL, NULL} /* Sentinel */
5374};
5375
5376
Barry Warsaw4a342091996-12-19 23:50:02 +00005377static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005378ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005379{
5380 PyObject* v = PyInt_FromLong(value);
5381 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5382 return -1; /* triggers fatal error */
5383
5384 Py_DECREF(v);
5385 return 0;
5386}
5387
Guido van Rossumd48f2521997-12-05 22:19:34 +00005388#if defined(PYOS_OS2)
5389/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5390static int insertvalues(PyObject *d)
5391{
5392 APIRET rc;
5393 ULONG values[QSV_MAX+1];
5394 PyObject *v;
5395 char *ver, tmp[10];
5396
5397 Py_BEGIN_ALLOW_THREADS
5398 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5399 Py_END_ALLOW_THREADS
5400
5401 if (rc != NO_ERROR) {
5402 os2_error(rc);
5403 return -1;
5404 }
5405
5406 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5407 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5408 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5409 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5410 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5411 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5412 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5413
5414 switch (values[QSV_VERSION_MINOR]) {
5415 case 0: ver = "2.00"; break;
5416 case 10: ver = "2.10"; break;
5417 case 11: ver = "2.11"; break;
5418 case 30: ver = "3.00"; break;
5419 case 40: ver = "4.00"; break;
5420 case 50: ver = "5.00"; break;
5421 default:
5422 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5423 values[QSV_VERSION_MINOR]);
5424 ver = &tmp[0];
5425 }
5426
5427 /* Add Indicator of the Version of the Operating System */
5428 v = PyString_FromString(ver);
5429 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5430 return -1;
5431 Py_DECREF(v);
5432
5433 /* Add Indicator of Which Drive was Used to Boot the System */
5434 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5435 tmp[1] = ':';
5436 tmp[2] = '\0';
5437
5438 v = PyString_FromString(tmp);
5439 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5440 return -1;
5441 Py_DECREF(v);
5442
5443 return 0;
5444}
5445#endif
5446
Barry Warsaw4a342091996-12-19 23:50:02 +00005447static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005448all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005449{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005450#ifdef F_OK
5451 if (ins(d, "F_OK", (long)F_OK)) return -1;
5452#endif
5453#ifdef R_OK
5454 if (ins(d, "R_OK", (long)R_OK)) return -1;
5455#endif
5456#ifdef W_OK
5457 if (ins(d, "W_OK", (long)W_OK)) return -1;
5458#endif
5459#ifdef X_OK
5460 if (ins(d, "X_OK", (long)X_OK)) return -1;
5461#endif
Fred Drakec9680921999-12-13 16:37:25 +00005462#ifdef NGROUPS_MAX
5463 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5464#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005465#ifdef TMP_MAX
5466 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5467#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005468#ifdef WNOHANG
5469 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5470#endif
5471#ifdef O_RDONLY
5472 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5473#endif
5474#ifdef O_WRONLY
5475 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5476#endif
5477#ifdef O_RDWR
5478 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5479#endif
5480#ifdef O_NDELAY
5481 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5482#endif
5483#ifdef O_NONBLOCK
5484 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5485#endif
5486#ifdef O_APPEND
5487 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5488#endif
5489#ifdef O_DSYNC
5490 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5491#endif
5492#ifdef O_RSYNC
5493 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5494#endif
5495#ifdef O_SYNC
5496 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5497#endif
5498#ifdef O_NOCTTY
5499 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5500#endif
5501#ifdef O_CREAT
5502 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5503#endif
5504#ifdef O_EXCL
5505 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5506#endif
5507#ifdef O_TRUNC
5508 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5509#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005510#ifdef O_BINARY
5511 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5512#endif
5513#ifdef O_TEXT
5514 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5515#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005516
Guido van Rossum246bc171999-02-01 23:54:31 +00005517#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005518 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5519 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5520 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5521 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5522 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005523#endif
5524
Guido van Rossumd48f2521997-12-05 22:19:34 +00005525#if defined(PYOS_OS2)
5526 if (insertvalues(d)) return -1;
5527#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005528 return 0;
5529}
5530
5531
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005532#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005533#define INITFUNC initnt
5534#define MODNAME "nt"
5535#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005536#if defined(PYOS_OS2)
5537#define INITFUNC initos2
5538#define MODNAME "os2"
5539#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005540#define INITFUNC initposix
5541#define MODNAME "posix"
5542#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005543#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005544
Guido van Rossum3886bb61998-12-04 18:50:17 +00005545DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005546INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005547{
Barry Warsaw53699e91996-12-10 23:23:01 +00005548 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005549
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005550 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005551 posix_methods,
5552 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005553 (PyObject *)NULL,
5554 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005555 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005556
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005557 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005558 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005559 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005560 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005561 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005562
Barry Warsaw4a342091996-12-19 23:50:02 +00005563 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005564 return;
5565
Fred Drakebec628d1999-12-15 18:31:10 +00005566 if (setup_confname_tables(d))
5567 return;
5568
Barry Warsawca74da41999-02-09 19:31:45 +00005569 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005570
Guido van Rossumb3d39562000-01-31 18:41:26 +00005571#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005572 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005573#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005574}