blob: d0de19128af22c9fea2cd61e0db6b13f0a29f0cd [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
111#ifdef NeXT
112/* NeXT's <unistd.h> and <utime.h> aren't worth much */
113#undef HAVE_UNISTD_H
114#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000115#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000116/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000117#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000118#endif
119
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000120#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000121#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000122extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000123#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000124#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000125extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000127extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000129#endif
130#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000131extern int chdir(char *);
132extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int chdir(const char *);
135extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000136#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int chmod(const char *, mode_t);
138extern int chown(const char *, uid_t, gid_t);
139extern char *getcwd(char *, int);
140extern char *strerror(int);
141extern int link(const char *, const char *);
142extern int rename(const char *, const char *);
143extern int stat(const char *, struct stat *);
144extern int unlink(const char *);
145extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000146#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000147extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000148#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000149#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000150extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000151#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000152#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000153
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000154#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155
Guido van Rossumb6775db1994-08-01 11:34:53 +0000156#ifdef HAVE_UTIME_H
157#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000158#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000159
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000160#ifdef HAVE_SYS_UTIME_H
161#include <sys/utime.h>
162#define HAVE_UTIME_H /* pretend we do for the rest of this file */
163#endif /* HAVE_SYS_UTIME_H */
164
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_SYS_TIMES_H
166#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000167#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168
169#ifdef HAVE_SYS_PARAM_H
170#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000171#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172
173#ifdef HAVE_SYS_UTSNAME_H
174#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000175#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000176
177#ifndef MAXPATHLEN
178#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000179#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000180
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000181#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000182#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000183#define NAMLEN(dirent) strlen((dirent)->d_name)
184#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000185#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000186#include <direct.h>
187#define NAMLEN(dirent) strlen((dirent)->d_name)
188#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000190#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000191#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000192#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000193#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000194#endif
195#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000197#endif
198#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000200#endif
201#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#include <direct.h>
205#include <io.h>
206#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000207#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000209#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000211#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#else /* 16-bit Windows */
213#include <dos.h>
214#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000215#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossumd48f2521997-12-05 22:19:34 +0000218#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000220#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000221
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000222#ifdef UNION_WAIT
223/* Emulate some macros on systems that have a union instead of macros */
224
225#ifndef WIFEXITED
226#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
227#endif
228
229#ifndef WEXITSTATUS
230#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
231#endif
232
233#ifndef WTERMSIG
234#define WTERMSIG(u_wait) ((u_wait).w_termsig)
235#endif
236
237#endif /* UNION_WAIT */
238
Greg Wardb48bc172000-03-01 21:51:56 +0000239/* Don't use the "_r" form if we don't need it (also, won't have a
240 prototype for it, at least on Solaris -- maybe others as well?). */
241#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
242#define USE_CTERMID_R
243#endif
244
245#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
246#define USE_TMPNAM_R
247#endif
248
Fred Drake699f3522000-06-29 21:12:41 +0000249/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000250#undef STAT
Fred Drake699f3522000-06-29 21:12:41 +0000251#ifdef MS_WIN64
252# define STAT _stati64
253# define FSTAT _fstati64
254# define STRUCT_STAT struct _stati64
255#else
256# define STAT stat
257# define FSTAT fstat
258# define STRUCT_STAT struct stat
259#endif
260
261
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000262/* Return a dictionary corresponding to the POSIX environment table */
263
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000264#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000265extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000266#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267
Barry Warsaw53699e91996-12-10 23:23:01 +0000268static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000269convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270{
Barry Warsaw53699e91996-12-10 23:23:01 +0000271 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000273 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274 if (d == NULL)
275 return NULL;
276 if (environ == NULL)
277 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000278 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000280 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000281 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282 char *p = strchr(*e, '=');
283 if (p == NULL)
284 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000285 k = PyString_FromStringAndSize(*e, (int)(p-*e));
286 if (k == NULL) {
287 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000289 }
290 v = PyString_FromString(p+1);
291 if (v == NULL) {
292 PyErr_Clear();
293 Py_DECREF(k);
294 continue;
295 }
296 if (PyDict_GetItem(d, k) == NULL) {
297 if (PyDict_SetItem(d, k, v) != 0)
298 PyErr_Clear();
299 }
300 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000301 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000303#if defined(PYOS_OS2)
304 {
305 APIRET rc;
306 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
307
308 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000309 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000310 PyObject *v = PyString_FromString(buffer);
311 PyDict_SetItemString(d, "BEGINLIBPATH", v);
312 Py_DECREF(v);
313 }
314 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
315 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
316 PyObject *v = PyString_FromString(buffer);
317 PyDict_SetItemString(d, "ENDLIBPATH", v);
318 Py_DECREF(v);
319 }
320 }
321#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322 return d;
323}
324
325
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000326/* Set a POSIX-specific error from errno, and return NULL */
327
Barry Warsawd58d7641998-07-23 16:14:40 +0000328static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000329posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000330{
Barry Warsawca74da41999-02-09 19:31:45 +0000331 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000332}
Barry Warsawd58d7641998-07-23 16:14:40 +0000333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000334posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000335{
Barry Warsawca74da41999-02-09 19:31:45 +0000336 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000337}
338
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000339#ifdef MS_WIN32
340static PyObject *
341win32_error(char* function, char* filename)
342{
Mark Hammond33a6da92000-08-15 00:46:38 +0000343 /* XXX We should pass the function name along in the future.
344 (_winreg.c also wants to pass the function name.)
345 This would however require an additional param to the
346 Windows error object, which is non-trivial.
347 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000348 errno = GetLastError();
349 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000350 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000351 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000352 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000353}
354#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000355
Guido van Rossumd48f2521997-12-05 22:19:34 +0000356#if defined(PYOS_OS2)
357/**********************************************************************
358 * Helper Function to Trim and Format OS/2 Messages
359 **********************************************************************/
360 static void
361os2_formatmsg(char *msgbuf, int msglen, char *reason)
362{
363 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
364
365 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
366 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
367
368 while (lastc > msgbuf && isspace(*lastc))
369 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
370 }
371
372 /* Add Optional Reason Text */
373 if (reason) {
374 strcat(msgbuf, " : ");
375 strcat(msgbuf, reason);
376 }
377}
378
379/**********************************************************************
380 * Decode an OS/2 Operating System Error Code
381 *
382 * A convenience function to lookup an OS/2 error code and return a
383 * text message we can use to raise a Python exception.
384 *
385 * Notes:
386 * The messages for errors returned from the OS/2 kernel reside in
387 * the file OSO001.MSG in the \OS2 directory hierarchy.
388 *
389 **********************************************************************/
390 static char *
391os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
392{
393 APIRET rc;
394 ULONG msglen;
395
396 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
397 Py_BEGIN_ALLOW_THREADS
398 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
399 errorcode, "oso001.msg", &msglen);
400 Py_END_ALLOW_THREADS
401
402 if (rc == NO_ERROR)
403 os2_formatmsg(msgbuf, msglen, reason);
404 else
405 sprintf(msgbuf, "unknown OS error #%d", errorcode);
406
407 return msgbuf;
408}
409
410/* Set an OS/2-specific error and return NULL. OS/2 kernel
411 errors are not in a global variable e.g. 'errno' nor are
412 they congruent with posix error numbers. */
413
414static PyObject * os2_error(int code)
415{
416 char text[1024];
417 PyObject *v;
418
419 os2_strerror(text, sizeof(text), code, "");
420
421 v = Py_BuildValue("(is)", code, text);
422 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000423 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000424 Py_DECREF(v);
425 }
426 return NULL; /* Signal to Python that an Exception is Pending */
427}
428
429#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000430
431/* POSIX generic methods */
432
Barry Warsaw53699e91996-12-10 23:23:01 +0000433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000434posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000435{
436 int fd;
437 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000438 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000439 return NULL;
440 Py_BEGIN_ALLOW_THREADS
441 res = (*func)(fd);
442 Py_END_ALLOW_THREADS
443 if (res < 0)
444 return posix_error();
445 Py_INCREF(Py_None);
446 return Py_None;
447}
448
449
450static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000451posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000452{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000453 char *path1;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000454 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000455 if (!PyArg_ParseTuple(args, format, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000456 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000457 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000458 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000459 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000460 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000461 return posix_error_with_filename(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000462 Py_INCREF(Py_None);
463 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000464}
465
Barry Warsaw53699e91996-12-10 23:23:01 +0000466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000467posix_2str(PyObject *args, char *format,
468 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000469{
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000470 char *path1, *path2;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000471 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000472 if (!PyArg_ParseTuple(args, format, &path1, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000473 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000474 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000475 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000476 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000477 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000478 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000479 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000480 Py_INCREF(Py_None);
481 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482}
483
Fred Drake699f3522000-06-29 21:12:41 +0000484/* pack a system stat C structure into the Python stat tuple
485 (used by posix_stat() and posix_fstat()) */
486static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000487_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000488{
489 PyObject *v = PyTuple_New(10);
490 if (v == NULL)
491 return NULL;
492
493 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
494#ifdef HAVE_LARGEFILE_SUPPORT
495 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
496#else
497 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
498#endif
499#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
500 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
501#else
502 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
503#endif
504 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
505 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
506 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
507#ifdef HAVE_LARGEFILE_SUPPORT
508 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
509#else
510 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
511#endif
512#if SIZEOF_TIME_T > SIZEOF_LONG
513 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
514 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
515 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
516#else
517 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
518 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
519 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
520#endif
521
522 if (PyErr_Occurred()) {
523 Py_DECREF(v);
524 return NULL;
525 }
526
527 return v;
528}
529
530
Barry Warsaw53699e91996-12-10 23:23:01 +0000531static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000532posix_do_stat(PyObject *self, PyObject *args, char *format,
533 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000534{
Fred Drake699f3522000-06-29 21:12:41 +0000535 STRUCT_STAT st;
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000536 char *path;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000537 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000538
539#ifdef MS_WIN32
540 int pathlen;
541 char pathcopy[MAX_PATH];
542#endif /* MS_WIN32 */
543
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000544 if (!PyArg_ParseTuple(args, format, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000545 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000546
547#ifdef MS_WIN32
548 pathlen = strlen(path);
549 /* the library call can blow up if the file name is too long! */
550 if (pathlen > MAX_PATH) {
551 errno = ENAMETOOLONG;
552 return posix_error();
553 }
554
555 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000556 /* exception for specific or current drive root */
557 if (!((pathlen == 1) ||
558 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000559 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000560 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000561 {
562 strncpy(pathcopy, path, pathlen);
563 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
564 path = pathcopy;
565 }
566 }
567#endif /* MS_WIN32 */
568
Barry Warsaw53699e91996-12-10 23:23:01 +0000569 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000570 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000571 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000572 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000573 return posix_error_with_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000574
575 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000576}
577
578
579/* POSIX methods */
580
Guido van Rossum94f6f721999-01-06 18:42:14 +0000581static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000582"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000583Test for access to a file.";
584
585static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000586posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000587{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000588 char *path;
589 int mode;
590 int res;
591
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000592 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000593 return NULL;
594 Py_BEGIN_ALLOW_THREADS
595 res = access(path, mode);
596 Py_END_ALLOW_THREADS
597 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000598}
599
Guido van Rossumd371ff11999-01-25 16:12:23 +0000600#ifndef F_OK
601#define F_OK 0
602#endif
603#ifndef R_OK
604#define R_OK 4
605#endif
606#ifndef W_OK
607#define W_OK 2
608#endif
609#ifndef X_OK
610#define X_OK 1
611#endif
612
613#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000614static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000615"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000616Return the name of the terminal device connected to 'fd'.";
617
618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000619posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000620{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000621 int id;
622 char *ret;
623
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000624 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000625 return NULL;
626
Guido van Rossum94f6f721999-01-06 18:42:14 +0000627 ret = ttyname(id);
628 if (ret == NULL)
629 return(posix_error());
630 return(PyString_FromString(ret));
631}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000632#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000633
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000634#ifdef HAVE_CTERMID
635static char posix_ctermid__doc__[] =
636"ctermid() -> String\n\
637Return the name of the controlling terminal for this process.";
638
639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000640posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000641{
642 char *ret;
643 char buffer[L_ctermid];
644
645 if (!PyArg_ParseTuple(args, ":ctermid"))
646 return NULL;
647
Greg Wardb48bc172000-03-01 21:51:56 +0000648#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000649 ret = ctermid_r(buffer);
650#else
651 ret = ctermid(buffer);
652#endif
653 if (ret == NULL)
654 return(posix_error());
655 return(PyString_FromString(buffer));
656}
657#endif
658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000659static char posix_chdir__doc__[] =
660"chdir(path) -> None\n\
661Change the current working directory to the specified path.";
662
Barry Warsaw53699e91996-12-10 23:23:01 +0000663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000664posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000665{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000666 return posix_1str(args, "s:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000667}
668
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000669
670static char posix_chmod__doc__[] =
671"chmod(path, mode) -> None\n\
672Change the access permissions of a file.";
673
Barry Warsaw53699e91996-12-10 23:23:01 +0000674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000675posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000676{
Guido van Rossumffd15f52000-03-31 00:47:28 +0000677 char *path;
678 int i;
679 int res;
Guido van Rossum49679b42000-03-31 00:48:21 +0000680 if (!PyArg_ParseTuple(args, "si", &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000681 return NULL;
682 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000683 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000684 Py_END_ALLOW_THREADS
685 if (res < 0)
686 return posix_error_with_filename(path);
687 Py_INCREF(Py_None);
688 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000689}
690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000691
Guido van Rossum21142a01999-01-08 21:05:37 +0000692#ifdef HAVE_FSYNC
693static char posix_fsync__doc__[] =
694"fsync(fildes) -> None\n\
695force write of file with filedescriptor to disk.";
696
697static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000698posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000699{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000700 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000701}
702#endif /* HAVE_FSYNC */
703
704#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000705
706#if defined(__hppa) || defined(hppa)
707extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
708#endif
709
Guido van Rossum21142a01999-01-08 21:05:37 +0000710static char posix_fdatasync__doc__[] =
711"fdatasync(fildes) -> None\n\
712force write of file with filedescriptor to disk.\n\
713 does not force update of metadata.";
714
715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000716posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000717{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000718 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000719}
720#endif /* HAVE_FDATASYNC */
721
722
Fredrik Lundh10723342000-07-10 16:38:09 +0000723#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000724static char posix_chown__doc__[] =
725"chown(path, uid, gid) -> None\n\
726Change the owner and group id of path to the numeric uid and gid.";
727
Barry Warsaw53699e91996-12-10 23:23:01 +0000728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000729posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000730{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000731 char *path;
732 int uid, gid;
733 int res;
734 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
735 return NULL;
736 Py_BEGIN_ALLOW_THREADS
737 res = chown(path, (uid_t) uid, (gid_t) gid);
738 Py_END_ALLOW_THREADS
739 if (res < 0)
740 return posix_error_with_filename(path);
741 Py_INCREF(Py_None);
742 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000743}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000744#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000745
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000746
Guido van Rossum36bc6801995-06-14 22:54:23 +0000747#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000748static char posix_getcwd__doc__[] =
749"getcwd() -> path\n\
750Return a string representing the current working directory.";
751
Barry Warsaw53699e91996-12-10 23:23:01 +0000752static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000753posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000754{
755 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000756 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000757 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000758 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000759 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000760 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000761 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000762 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000763 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000764 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000765}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000766#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000768
Guido van Rossumb6775db1994-08-01 11:34:53 +0000769#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000770static char posix_link__doc__[] =
771"link(src, dst) -> None\n\
772Create a hard link to a file.";
773
Barry Warsaw53699e91996-12-10 23:23:01 +0000774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000775posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000776{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000777 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000778}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000779#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000781
782static char posix_listdir__doc__[] =
783"listdir(path) -> list_of_strings\n\
784Return a list containing the names of the entries in the directory.\n\
785\n\
786 path: path of directory to list\n\
787\n\
788The list is in arbitrary order. It does not include the special\n\
789entries '.' and '..' even if they are present in the directory.";
790
Barry Warsaw53699e91996-12-10 23:23:01 +0000791static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000792posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000793{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000794 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000795 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000796#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000797
Guido van Rossumb6775db1994-08-01 11:34:53 +0000798 char *name;
799 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000800 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000801 HANDLE hFindFile;
802 WIN32_FIND_DATA FileData;
803 char namebuf[MAX_PATH+5];
Tim Peters0bb44a42000-09-15 07:44:49 +0000804 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000805
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000806 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000807 return NULL;
808 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000809 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000810 return NULL;
811 }
812 strcpy(namebuf, name);
Tim Peters0bb44a42000-09-15 07:44:49 +0000813 ch = namebuf[len-1];
814 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000815 namebuf[len++] = '/';
816 strcpy(namebuf + len, "*.*");
817
Barry Warsaw53699e91996-12-10 23:23:01 +0000818 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000819 return NULL;
820
821 hFindFile = FindFirstFile(namebuf, &FileData);
822 if (hFindFile == INVALID_HANDLE_VALUE) {
823 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000824 if (errno == ERROR_FILE_NOT_FOUND)
825 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000826 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000827 }
828 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000829 if (FileData.cFileName[0] == '.' &&
830 (FileData.cFileName[1] == '\0' ||
831 FileData.cFileName[1] == '.' &&
832 FileData.cFileName[2] == '\0'))
833 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000834 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000835 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000836 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000837 d = NULL;
838 break;
839 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000840 if (PyList_Append(d, v) != 0) {
841 Py_DECREF(v);
842 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000843 d = NULL;
844 break;
845 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000846 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000847 } while (FindNextFile(hFindFile, &FileData) == TRUE);
848
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000849 if (FindClose(hFindFile) == FALSE)
850 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000851
852 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000853
Tim Peters0bb44a42000-09-15 07:44:49 +0000854#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000855
856#ifndef MAX_PATH
857#define MAX_PATH 250
858#endif
859 char *name, *pt;
860 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000861 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000862 char namebuf[MAX_PATH+5];
863 struct _find_t ep;
864
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000865 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000866 return NULL;
867 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000868 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000869 return NULL;
870 }
871 strcpy(namebuf, name);
872 for (pt = namebuf; *pt; pt++)
873 if (*pt == '/')
874 *pt = '\\';
875 if (namebuf[len-1] != '\\')
876 namebuf[len++] = '\\';
877 strcpy(namebuf + len, "*.*");
878
Barry Warsaw53699e91996-12-10 23:23:01 +0000879 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000880 return NULL;
881
882 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000883 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
884 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000885 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000886 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000887 }
888 do {
889 if (ep.name[0] == '.' &&
890 (ep.name[1] == '\0' ||
891 ep.name[1] == '.' &&
892 ep.name[2] == '\0'))
893 continue;
894 strcpy(namebuf, ep.name);
895 for (pt = namebuf; *pt; pt++)
896 if (isupper(*pt))
897 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000898 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000899 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000900 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000901 d = NULL;
902 break;
903 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000904 if (PyList_Append(d, v) != 0) {
905 Py_DECREF(v);
906 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000907 d = NULL;
908 break;
909 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000910 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000911 } while (_dos_findnext(&ep) == 0);
912
913 return d;
914
Tim Peters0bb44a42000-09-15 07:44:49 +0000915#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000916
917#ifndef MAX_PATH
918#define MAX_PATH CCHMAXPATH
919#endif
920 char *name, *pt;
921 int len;
922 PyObject *d, *v;
923 char namebuf[MAX_PATH+5];
924 HDIR hdir = 1;
925 ULONG srchcnt = 1;
926 FILEFINDBUF3 ep;
927 APIRET rc;
928
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000929 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000930 return NULL;
931 if (len >= MAX_PATH) {
932 PyErr_SetString(PyExc_ValueError, "path too long");
933 return NULL;
934 }
935 strcpy(namebuf, name);
936 for (pt = namebuf; *pt; pt++)
937 if (*pt == '/')
938 *pt = '\\';
939 if (namebuf[len-1] != '\\')
940 namebuf[len++] = '\\';
941 strcpy(namebuf + len, "*.*");
942
943 if ((d = PyList_New(0)) == NULL)
944 return NULL;
945
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000946 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
947 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000948 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000949 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
950 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
951 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000952
953 if (rc != NO_ERROR) {
954 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000955 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000956 }
957
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000958 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959 do {
960 if (ep.achName[0] == '.'
961 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000962 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963
964 strcpy(namebuf, ep.achName);
965
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000966 /* Leave Case of Name Alone -- In Native Form */
967 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000968
969 v = PyString_FromString(namebuf);
970 if (v == NULL) {
971 Py_DECREF(d);
972 d = NULL;
973 break;
974 }
975 if (PyList_Append(d, v) != 0) {
976 Py_DECREF(v);
977 Py_DECREF(d);
978 d = NULL;
979 break;
980 }
981 Py_DECREF(v);
982 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
983 }
984
985 return d;
986#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000987
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000988 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +0000989 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000990 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000991 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000992 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000993 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000994 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000995 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000996 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000997 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000998 closedir(dirp);
999 return NULL;
1000 }
1001 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001002 if (ep->d_name[0] == '.' &&
1003 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001004 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001005 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001006 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001007 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001008 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001009 d = NULL;
1010 break;
1011 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001012 if (PyList_Append(d, v) != 0) {
1013 Py_DECREF(v);
1014 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001015 d = NULL;
1016 break;
1017 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001018 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019 }
1020 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001021
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001022 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001023
Tim Peters0bb44a42000-09-15 07:44:49 +00001024#endif /* which OS */
1025} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001026
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001027static char posix_mkdir__doc__[] =
1028"mkdir(path [, mode=0777]) -> None\n\
1029Create a directory.";
1030
Barry Warsaw53699e91996-12-10 23:23:01 +00001031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001032posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001033{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001034 int res;
1035 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001036 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001037 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001038 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001039 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001040#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001041 res = mkdir(path);
1042#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001043 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001044#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001045 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001046 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001047 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001048 Py_INCREF(Py_None);
1049 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001050}
1051
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001052
Guido van Rossumb6775db1994-08-01 11:34:53 +00001053#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001054static char posix_nice__doc__[] =
1055"nice(inc) -> new_priority\n\
1056Decrease the priority of process and return new priority.";
1057
Barry Warsaw53699e91996-12-10 23:23:01 +00001058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001059posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001060{
1061 int increment, value;
1062
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001063 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001064 return NULL;
1065 value = nice(increment);
1066 if (value == -1)
1067 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001068 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001069}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001070#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001071
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001072
1073static char posix_rename__doc__[] =
1074"rename(old, new) -> None\n\
1075Rename a file or directory.";
1076
Barry Warsaw53699e91996-12-10 23:23:01 +00001077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001078posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001079{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001080 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001081}
1082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001083
1084static char posix_rmdir__doc__[] =
1085"rmdir(path) -> None\n\
1086Remove a directory.";
1087
Barry Warsaw53699e91996-12-10 23:23:01 +00001088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001089posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001090{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001091 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001092}
1093
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001094
1095static char posix_stat__doc__[] =
1096"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1097Perform a stat system call on the given path.";
1098
Barry Warsaw53699e91996-12-10 23:23:01 +00001099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001100posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001101{
Fred Drake699f3522000-06-29 21:12:41 +00001102 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001103}
1104
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001105
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001106#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001107static char posix_system__doc__[] =
1108"system(command) -> exit_status\n\
1109Execute the command (a string) in a subshell.";
1110
Barry Warsaw53699e91996-12-10 23:23:01 +00001111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001112posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001113{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001114 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001115 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001116 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001117 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001118 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001119 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001120 Py_END_ALLOW_THREADS
1121 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001122}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001123#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001124
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001125
1126static char posix_umask__doc__[] =
1127"umask(new_mask) -> old_mask\n\
1128Set the current numeric umask and return the previous umask.";
1129
Barry Warsaw53699e91996-12-10 23:23:01 +00001130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001131posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132{
1133 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001134 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135 return NULL;
1136 i = umask(i);
1137 if (i < 0)
1138 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001139 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001140}
1141
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001142
1143static char posix_unlink__doc__[] =
1144"unlink(path) -> None\n\
1145Remove a file (same as remove(path)).";
1146
1147static char posix_remove__doc__[] =
1148"remove(path) -> None\n\
1149Remove a file (same as unlink(path)).";
1150
Barry Warsaw53699e91996-12-10 23:23:01 +00001151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001152posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001154 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155}
1156
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001157
Guido van Rossumb6775db1994-08-01 11:34:53 +00001158#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001159static char posix_uname__doc__[] =
1160"uname() -> (sysname, nodename, release, version, machine)\n\
1161Return a tuple identifying the current operating system.";
1162
Barry Warsaw53699e91996-12-10 23:23:01 +00001163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001164posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001165{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001166 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001167 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001168 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001169 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001170 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001171 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001172 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001173 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001174 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001175 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001176 u.sysname,
1177 u.nodename,
1178 u.release,
1179 u.version,
1180 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001181}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001182#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001183
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001184
1185static char posix_utime__doc__[] =
1186"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001187utime(path, None) -> None\n\
1188Set the access and modified time of the file to the given values. If the\n\
1189second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001190
Barry Warsaw53699e91996-12-10 23:23:01 +00001191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001192posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001193{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001194 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001195 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001196 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001197 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001198
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001199/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001200#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001201 struct utimbuf buf;
1202#define ATIME buf.actime
1203#define MTIME buf.modtime
1204#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001205#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001206 time_t buf[2];
1207#define ATIME buf[0]
1208#define MTIME buf[1]
1209#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001210#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001211
Barry Warsaw3cef8562000-05-01 16:17:24 +00001212 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001214 if (arg == Py_None) {
1215 /* optional time values not given */
1216 Py_BEGIN_ALLOW_THREADS
1217 res = utime(path, NULL);
1218 Py_END_ALLOW_THREADS
1219 }
1220 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1221 PyErr_SetString(PyExc_TypeError,
1222 "Second argument must be a 2-tuple of numbers.");
1223 return NULL;
1224 }
1225 else {
1226 ATIME = atime;
1227 MTIME = mtime;
1228 Py_BEGIN_ALLOW_THREADS
1229 res = utime(path, UTIME_ARG);
1230 Py_END_ALLOW_THREADS
1231 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001232 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001233 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001234 Py_INCREF(Py_None);
1235 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001236#undef UTIME_ARG
1237#undef ATIME
1238#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001239}
1240
Guido van Rossum85e3b011991-06-03 12:42:10 +00001241
Guido van Rossum3b066191991-06-04 19:40:25 +00001242/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001243
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001244static char posix__exit__doc__[] =
1245"_exit(status)\n\
1246Exit to the system with specified status, without normal exit processing.";
1247
Barry Warsaw53699e91996-12-10 23:23:01 +00001248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001249posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001250{
1251 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001252 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001253 return NULL;
1254 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001255 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001256}
1257
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001258
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001259#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001260static char posix_execv__doc__[] =
1261"execv(path, args)\n\
1262Execute an executable path with arguments, replacing current process.\n\
1263\n\
1264 path: path of executable file\n\
1265 args: tuple or list of strings";
1266
Barry Warsaw53699e91996-12-10 23:23:01 +00001267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001268posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001269{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001270 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001271 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001272 char **argvlist;
1273 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001274 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001275
Guido van Rossum89b33251993-10-22 14:26:06 +00001276 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001277 argv is a list or tuple of strings. */
1278
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001279 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001280 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001281 if (PyList_Check(argv)) {
1282 argc = PyList_Size(argv);
1283 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001284 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001285 else if (PyTuple_Check(argv)) {
1286 argc = PyTuple_Size(argv);
1287 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001288 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001289 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001290 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1291 return NULL;
1292 }
1293
1294 if (argc == 0) {
1295 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001296 return NULL;
1297 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001298
Barry Warsaw53699e91996-12-10 23:23:01 +00001299 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001300 if (argvlist == NULL)
1301 return NULL;
1302 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001303 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1304 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001305 PyErr_SetString(PyExc_TypeError,
1306 "all arguments must be strings");
1307 return NULL;
1308
Guido van Rossum85e3b011991-06-03 12:42:10 +00001309 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001310 }
1311 argvlist[argc] = NULL;
1312
Guido van Rossumb6775db1994-08-01 11:34:53 +00001313#ifdef BAD_EXEC_PROTOTYPES
1314 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001315#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001316 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001317#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001318
Guido van Rossum85e3b011991-06-03 12:42:10 +00001319 /* If we get here it's definitely an error */
1320
Barry Warsaw53699e91996-12-10 23:23:01 +00001321 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001322 return posix_error();
1323}
1324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001325
1326static char posix_execve__doc__[] =
1327"execve(path, args, env)\n\
1328Execute a path with arguments and environment, replacing current process.\n\
1329\n\
1330 path: path of executable file\n\
1331 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001332 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001333
Barry Warsaw53699e91996-12-10 23:23:01 +00001334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001335posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001336{
1337 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001338 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001339 char **argvlist;
1340 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001341 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001342 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001343 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001344
1345 /* execve has three arguments: (path, argv, env), where
1346 argv is a list or tuple of strings and env is a dictionary
1347 like posix.environ. */
1348
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001349 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001350 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001351 if (PyList_Check(argv)) {
1352 argc = PyList_Size(argv);
1353 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001354 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001355 else if (PyTuple_Check(argv)) {
1356 argc = PyTuple_Size(argv);
1357 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001358 }
1359 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001360 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001361 return NULL;
1362 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001363 if (!PyMapping_Check(env)) {
1364 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001365 return NULL;
1366 }
1367
Guido van Rossum50422b42000-04-26 20:34:28 +00001368 if (argc == 0) {
1369 PyErr_SetString(PyExc_ValueError,
1370 "empty argument list");
1371 return NULL;
1372 }
1373
Barry Warsaw53699e91996-12-10 23:23:01 +00001374 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001375 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001376 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001377 return NULL;
1378 }
1379 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001380 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001381 "s;argv must be list of strings",
1382 &argvlist[i]))
1383 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001384 goto fail_1;
1385 }
1386 }
1387 argvlist[argc] = NULL;
1388
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001389 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001390 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001391 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001392 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001393 goto fail_1;
1394 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001395 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001396 keys = PyMapping_Keys(env);
1397 vals = PyMapping_Values(env);
1398 if (!keys || !vals)
1399 goto fail_2;
1400
1401 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001402 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001403
1404 key = PyList_GetItem(keys, pos);
1405 val = PyList_GetItem(vals, pos);
1406 if (!key || !val)
1407 goto fail_2;
1408
Barry Warsaw53699e91996-12-10 23:23:01 +00001409 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001410 !PyArg_Parse(val, "s;non-string value in env", &v))
1411 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001412 goto fail_2;
1413 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001414
1415#if defined(PYOS_OS2)
1416 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1417 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1418#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001419 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001420 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001421 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001422 goto fail_2;
1423 }
1424 sprintf(p, "%s=%s", k, v);
1425 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001426#if defined(PYOS_OS2)
1427 }
1428#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001429 }
1430 envlist[envc] = 0;
1431
Guido van Rossumb6775db1994-08-01 11:34:53 +00001432
1433#ifdef BAD_EXEC_PROTOTYPES
1434 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001435#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001436 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001437#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001438
1439 /* If we get here it's definitely an error */
1440
1441 (void) posix_error();
1442
1443 fail_2:
1444 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001445 PyMem_DEL(envlist[envc]);
1446 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001447 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001448 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001449 Py_XDECREF(vals);
1450 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001451 return NULL;
1452}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001453#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001454
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001455
Guido van Rossuma1065681999-01-25 23:20:23 +00001456#ifdef HAVE_SPAWNV
1457static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001458"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001459Execute an executable path with arguments, replacing current process.\n\
1460\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001461 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001462 path: path of executable file\n\
1463 args: tuple or list of strings";
1464
1465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001466posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001467{
1468 char *path;
1469 PyObject *argv;
1470 char **argvlist;
1471 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001472 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001473 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001474
1475 /* spawnv has three arguments: (mode, path, argv), where
1476 argv is a list or tuple of strings. */
1477
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001478 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001479 return NULL;
1480 if (PyList_Check(argv)) {
1481 argc = PyList_Size(argv);
1482 getitem = PyList_GetItem;
1483 }
1484 else if (PyTuple_Check(argv)) {
1485 argc = PyTuple_Size(argv);
1486 getitem = PyTuple_GetItem;
1487 }
1488 else {
Fred Drake137507e2000-06-01 02:02:46 +00001489 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001490 return NULL;
1491 }
1492
1493 argvlist = PyMem_NEW(char *, argc+1);
1494 if (argvlist == NULL)
1495 return NULL;
1496 for (i = 0; i < argc; i++) {
1497 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1498 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001499 PyErr_SetString(PyExc_TypeError,
1500 "all arguments must be strings");
1501 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001502 }
1503 }
1504 argvlist[argc] = NULL;
1505
Guido van Rossum246bc171999-02-01 23:54:31 +00001506 if (mode == _OLD_P_OVERLAY)
1507 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001508 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001509
1510 PyMem_DEL(argvlist);
1511
Fred Drake699f3522000-06-29 21:12:41 +00001512 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001513 return posix_error();
1514 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001515#if SIZEOF_LONG == SIZEOF_VOID_P
1516 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001517#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001518 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001519#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001520}
1521
1522
1523static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001524"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001525Execute a path with arguments and environment, replacing current process.\n\
1526\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001527 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001528 path: path of executable file\n\
1529 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001530 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001531
1532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001533posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001534{
1535 char *path;
1536 PyObject *argv, *env;
1537 char **argvlist;
1538 char **envlist;
1539 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1540 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001541 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001542 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001543
1544 /* spawnve has four arguments: (mode, path, argv, env), where
1545 argv is a list or tuple of strings and env is a dictionary
1546 like posix.environ. */
1547
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001548 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001549 return NULL;
1550 if (PyList_Check(argv)) {
1551 argc = PyList_Size(argv);
1552 getitem = PyList_GetItem;
1553 }
1554 else if (PyTuple_Check(argv)) {
1555 argc = PyTuple_Size(argv);
1556 getitem = PyTuple_GetItem;
1557 }
1558 else {
1559 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1560 return NULL;
1561 }
1562 if (!PyMapping_Check(env)) {
1563 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1564 return NULL;
1565 }
1566
1567 argvlist = PyMem_NEW(char *, argc+1);
1568 if (argvlist == NULL) {
1569 PyErr_NoMemory();
1570 return NULL;
1571 }
1572 for (i = 0; i < argc; i++) {
1573 if (!PyArg_Parse((*getitem)(argv, i),
1574 "s;argv must be list of strings",
1575 &argvlist[i]))
1576 {
1577 goto fail_1;
1578 }
1579 }
1580 argvlist[argc] = NULL;
1581
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001582 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001583 envlist = PyMem_NEW(char *, i + 1);
1584 if (envlist == NULL) {
1585 PyErr_NoMemory();
1586 goto fail_1;
1587 }
1588 envc = 0;
1589 keys = PyMapping_Keys(env);
1590 vals = PyMapping_Values(env);
1591 if (!keys || !vals)
1592 goto fail_2;
1593
1594 for (pos = 0; pos < i; pos++) {
1595 char *p, *k, *v;
1596
1597 key = PyList_GetItem(keys, pos);
1598 val = PyList_GetItem(vals, pos);
1599 if (!key || !val)
1600 goto fail_2;
1601
1602 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1603 !PyArg_Parse(val, "s;non-string value in env", &v))
1604 {
1605 goto fail_2;
1606 }
1607 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1608 if (p == NULL) {
1609 PyErr_NoMemory();
1610 goto fail_2;
1611 }
1612 sprintf(p, "%s=%s", k, v);
1613 envlist[envc++] = p;
1614 }
1615 envlist[envc] = 0;
1616
Guido van Rossum246bc171999-02-01 23:54:31 +00001617 if (mode == _OLD_P_OVERLAY)
1618 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001619 spawnval = _spawnve(mode, path, argvlist, envlist);
1620 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001621 (void) posix_error();
1622 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001623#if SIZEOF_LONG == SIZEOF_VOID_P
1624 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001625#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001626 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001627#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001628
1629 fail_2:
1630 while (--envc >= 0)
1631 PyMem_DEL(envlist[envc]);
1632 PyMem_DEL(envlist);
1633 fail_1:
1634 PyMem_DEL(argvlist);
1635 Py_XDECREF(vals);
1636 Py_XDECREF(keys);
1637 return res;
1638}
1639#endif /* HAVE_SPAWNV */
1640
1641
Guido van Rossumad0ee831995-03-01 10:34:45 +00001642#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001643static char posix_fork__doc__[] =
1644"fork() -> pid\n\
1645Fork a child process.\n\
1646\n\
1647Return 0 to child process and PID of child to parent process.";
1648
Barry Warsaw53699e91996-12-10 23:23:01 +00001649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001650posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001651{
1652 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001653 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001654 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001655 pid = fork();
1656 if (pid == -1)
1657 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001658 if (pid == 0)
1659 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001660 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001661}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001662#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001663
Fred Drake8cef4cf2000-06-28 16:40:38 +00001664#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1665#ifdef HAVE_PTY_H
1666#include <pty.h>
1667#else
1668#ifdef HAVE_LIBUTIL_H
1669#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001670#endif /* HAVE_LIBUTIL_H */
1671#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001672#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001673
Thomas Wouters70c21a12000-07-14 14:28:33 +00001674#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001675static char posix_openpty__doc__[] =
1676"openpty() -> (master_fd, slave_fd)\n\
1677Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1678
1679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001680posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001681{
1682 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001683#ifndef HAVE_OPENPTY
1684 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001685#endif
1686
Fred Drake8cef4cf2000-06-28 16:40:38 +00001687 if (!PyArg_ParseTuple(args, ":openpty"))
1688 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001689
1690#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001691 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1692 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001693#else
1694 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1695 if (slave_name == NULL)
1696 return posix_error();
1697
1698 slave_fd = open(slave_name, O_RDWR);
1699 if (slave_fd < 0)
1700 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001701#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001702
Fred Drake8cef4cf2000-06-28 16:40:38 +00001703 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001704
Fred Drake8cef4cf2000-06-28 16:40:38 +00001705}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001706#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001707
1708#ifdef HAVE_FORKPTY
1709static char posix_forkpty__doc__[] =
1710"forkpty() -> (pid, master_fd)\n\
1711Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1712Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1713To both, return fd of newly opened pseudo-terminal.\n";
1714
1715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001716posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001717{
1718 int master_fd, pid;
1719
1720 if (!PyArg_ParseTuple(args, ":forkpty"))
1721 return NULL;
1722 pid = forkpty(&master_fd, NULL, NULL, NULL);
1723 if (pid == -1)
1724 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001725 if (pid == 0)
1726 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001727 return Py_BuildValue("(ii)", pid, master_fd);
1728}
1729#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001730
Guido van Rossumad0ee831995-03-01 10:34:45 +00001731#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001732static char posix_getegid__doc__[] =
1733"getegid() -> egid\n\
1734Return the current process's effective group id.";
1735
Barry Warsaw53699e91996-12-10 23:23:01 +00001736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001737posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001738{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001739 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001740 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001741 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001742}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001743#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001744
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001745
Guido van Rossumad0ee831995-03-01 10:34:45 +00001746#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001747static char posix_geteuid__doc__[] =
1748"geteuid() -> euid\n\
1749Return the current process's effective user id.";
1750
Barry Warsaw53699e91996-12-10 23:23:01 +00001751static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001752posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001753{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001754 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001755 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001756 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001757}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001758#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001760
Guido van Rossumad0ee831995-03-01 10:34:45 +00001761#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001762static char posix_getgid__doc__[] =
1763"getgid() -> gid\n\
1764Return the current process's group id.";
1765
Barry Warsaw53699e91996-12-10 23:23:01 +00001766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001767posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001768{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001769 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001770 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001771 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001772}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001773#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001774
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001775
1776static char posix_getpid__doc__[] =
1777"getpid() -> pid\n\
1778Return the current process id";
1779
Barry Warsaw53699e91996-12-10 23:23:01 +00001780static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001781posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001782{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001783 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001784 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001785 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001786}
1787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001788
Fred Drakec9680921999-12-13 16:37:25 +00001789#ifdef HAVE_GETGROUPS
1790static char posix_getgroups__doc__[] = "\
1791getgroups() -> list of group IDs\n\
1792Return list of supplemental group IDs for the process.";
1793
1794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001795posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001796{
1797 PyObject *result = NULL;
1798
1799 if (PyArg_ParseTuple(args, ":getgroups")) {
1800#ifdef NGROUPS_MAX
1801#define MAX_GROUPS NGROUPS_MAX
1802#else
1803 /* defined to be 16 on Solaris7, so this should be a small number */
1804#define MAX_GROUPS 64
1805#endif
1806 gid_t grouplist[MAX_GROUPS];
1807 int n;
1808
1809 n = getgroups(MAX_GROUPS, grouplist);
1810 if (n < 0)
1811 posix_error();
1812 else {
1813 result = PyList_New(n);
1814 if (result != NULL) {
1815 PyObject *o;
1816 int i;
1817 for (i = 0; i < n; ++i) {
1818 o = PyInt_FromLong((long)grouplist[i]);
1819 if (o == NULL) {
1820 Py_DECREF(result);
1821 result = NULL;
1822 break;
1823 }
1824 PyList_SET_ITEM(result, i, o);
1825 }
1826 }
1827 }
1828 }
1829 return result;
1830}
1831#endif
1832
Guido van Rossumb6775db1994-08-01 11:34:53 +00001833#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001834static char posix_getpgrp__doc__[] =
1835"getpgrp() -> pgrp\n\
1836Return the current process group id.";
1837
Barry Warsaw53699e91996-12-10 23:23:01 +00001838static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001839posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001840{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001841 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001842 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001843#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001844 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001845#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001846 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001847#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001848}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001849#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001850
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001851
Guido van Rossumb6775db1994-08-01 11:34:53 +00001852#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001853static char posix_setpgrp__doc__[] =
1854"setpgrp() -> None\n\
1855Make this process a session leader.";
1856
Barry Warsaw53699e91996-12-10 23:23:01 +00001857static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001858posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001859{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001860 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001861 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001862#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001863 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001864#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001865 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001866#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001867 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001868 Py_INCREF(Py_None);
1869 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001870}
1871
Guido van Rossumb6775db1994-08-01 11:34:53 +00001872#endif /* HAVE_SETPGRP */
1873
Guido van Rossumad0ee831995-03-01 10:34:45 +00001874#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001875static char posix_getppid__doc__[] =
1876"getppid() -> ppid\n\
1877Return the parent's process id.";
1878
Barry Warsaw53699e91996-12-10 23:23:01 +00001879static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001880posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001881{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001882 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001883 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001884 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001885}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001886#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001888
Fred Drake12c6e2d1999-12-14 21:25:03 +00001889#ifdef HAVE_GETLOGIN
1890static char posix_getlogin__doc__[] = "\
1891getlogin() -> string\n\
1892Return the actual login name.";
1893
1894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001895posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001896{
1897 PyObject *result = NULL;
1898
1899 if (PyArg_ParseTuple(args, ":getlogin")) {
1900 char *name = getlogin();
1901
1902 if (name == NULL)
1903 posix_error();
1904 else
1905 result = PyString_FromString(name);
1906 }
1907 return result;
1908}
1909#endif
1910
Guido van Rossumad0ee831995-03-01 10:34:45 +00001911#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001912static char posix_getuid__doc__[] =
1913"getuid() -> uid\n\
1914Return the current process's user id.";
1915
Barry Warsaw53699e91996-12-10 23:23:01 +00001916static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001917posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001918{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001919 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001920 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001921 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001922}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001923#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001924
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001925
Guido van Rossumad0ee831995-03-01 10:34:45 +00001926#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001927static char posix_kill__doc__[] =
1928"kill(pid, sig) -> None\n\
1929Kill a process with a signal.";
1930
Barry Warsaw53699e91996-12-10 23:23:01 +00001931static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001932posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001933{
1934 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001935 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001936 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001937#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001938 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1939 APIRET rc;
1940 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001941 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001942
1943 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1944 APIRET rc;
1945 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001946 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001947
1948 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001949 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001950#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001951 if (kill(pid, sig) == -1)
1952 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001953#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001954 Py_INCREF(Py_None);
1955 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001956}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001957#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001958
Guido van Rossumc0125471996-06-28 18:55:32 +00001959#ifdef HAVE_PLOCK
1960
1961#ifdef HAVE_SYS_LOCK_H
1962#include <sys/lock.h>
1963#endif
1964
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001965static char posix_plock__doc__[] =
1966"plock(op) -> None\n\
1967Lock program segments into memory.";
1968
Barry Warsaw53699e91996-12-10 23:23:01 +00001969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001970posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001971{
1972 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001973 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001974 return NULL;
1975 if (plock(op) == -1)
1976 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001977 Py_INCREF(Py_None);
1978 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00001979}
1980#endif
1981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001982
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001983#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001984static char posix_popen__doc__[] =
1985"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
1986Open a pipe to/from a command returning a file object.";
1987
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001988#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001989static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001990async_system(const char *command)
1991{
1992 char *p, errormsg[256], args[1024];
1993 RESULTCODES rcodes;
1994 APIRET rc;
1995 char *shell = getenv("COMSPEC");
1996 if (!shell)
1997 shell = "cmd";
1998
1999 strcpy(args, shell);
2000 p = &args[ strlen(args)+1 ];
2001 strcpy(p, "/c ");
2002 strcat(p, command);
2003 p += strlen(p) + 1;
2004 *p = '\0';
2005
2006 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002007 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002008 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002009 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002010 &rcodes, shell);
2011 return rc;
2012}
2013
Guido van Rossumd48f2521997-12-05 22:19:34 +00002014static FILE *
2015popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002016{
2017 HFILE rhan, whan;
2018 FILE *retfd = NULL;
2019 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2020
Guido van Rossumd48f2521997-12-05 22:19:34 +00002021 if (rc != NO_ERROR) {
2022 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002023 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002024 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002025
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002026 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2027 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002028
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002029 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2030 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002031
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002032 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2033 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002034
2035 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002036 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002037 }
2038
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002039 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2040 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002041
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002042 close(oldfd); /* And Close Saved STDOUT Handle */
2043 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002044
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002045 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2046 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002047
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002048 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2049 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002050
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002051 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2052 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002053
2054 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002055 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002056 }
2057
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002058 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2059 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002060
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002061 close(oldfd); /* And Close Saved STDIN Handle */
2062 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002063
Guido van Rossumd48f2521997-12-05 22:19:34 +00002064 } else {
2065 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002066 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002067 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002068}
2069
2070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002071posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002072{
2073 char *name;
2074 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002075 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002076 FILE *fp;
2077 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002078 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002079 return NULL;
2080 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002081 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002082 Py_END_ALLOW_THREADS
2083 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002084 return os2_error(err);
2085
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002086 f = PyFile_FromFile(fp, name, mode, fclose);
2087 if (f != NULL)
2088 PyFile_SetBufSize(f, bufsize);
2089 return f;
2090}
2091
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002092#elif defined(MS_WIN32)
2093
2094/*
2095 * Portable 'popen' replacement for Win32.
2096 *
2097 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2098 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002099 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002100 */
2101
2102#include <malloc.h>
2103#include <io.h>
2104#include <fcntl.h>
2105
2106/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2107#define POPEN_1 1
2108#define POPEN_2 2
2109#define POPEN_3 3
2110#define POPEN_4 4
2111
2112static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002113static int _PyPclose(FILE *file);
2114
2115/*
2116 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002117 * for use when retrieving the process exit code. See _PyPclose() below
2118 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002119 */
2120static PyObject *_PyPopenProcs = NULL;
2121
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002122
2123/* popen that works from a GUI.
2124 *
2125 * The result of this function is a pipe (file) connected to the
2126 * processes stdin or stdout, depending on the requested mode.
2127 */
2128
2129static PyObject *
2130posix_popen(PyObject *self, PyObject *args)
2131{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002132 PyObject *f, *s;
2133 int tm = 0;
2134
2135 char *cmdstring;
2136 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002137 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002138 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002139 return NULL;
2140
2141 s = PyTuple_New(0);
2142
2143 if (*mode == 'r')
2144 tm = _O_RDONLY;
2145 else if (*mode != 'w') {
2146 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2147 return NULL;
2148 } else
2149 tm = _O_WRONLY;
2150
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002151 if (bufsize != -1) {
2152 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2153 return NULL;
2154 }
2155
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002156 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002157 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002158 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002159 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002160 else
2161 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2162
2163 return f;
2164}
2165
2166/* Variation on win32pipe.popen
2167 *
2168 * The result of this function is a pipe (file) connected to the
2169 * process's stdin, and a pipe connected to the process's stdout.
2170 */
2171
2172static PyObject *
2173win32_popen2(PyObject *self, PyObject *args)
2174{
2175 PyObject *f;
2176 int tm=0;
2177
2178 char *cmdstring;
2179 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002180 int bufsize = -1;
2181 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002182 return NULL;
2183
2184 if (*mode == 't')
2185 tm = _O_TEXT;
2186 else if (*mode != 'b') {
2187 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2188 return NULL;
2189 } else
2190 tm = _O_BINARY;
2191
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002192 if (bufsize != -1) {
2193 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2194 return NULL;
2195 }
2196
2197 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002198
2199 return f;
2200}
2201
2202/*
2203 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002204 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002205 * The result of this function is 3 pipes - the process's stdin,
2206 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002207 */
2208
2209static PyObject *
2210win32_popen3(PyObject *self, PyObject *args)
2211{
2212 PyObject *f;
2213 int tm = 0;
2214
2215 char *cmdstring;
2216 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002217 int bufsize = -1;
2218 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002219 return NULL;
2220
2221 if (*mode == 't')
2222 tm = _O_TEXT;
2223 else if (*mode != 'b') {
2224 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2225 return NULL;
2226 } else
2227 tm = _O_BINARY;
2228
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002229 if (bufsize != -1) {
2230 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2231 return NULL;
2232 }
2233
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002234 f = _PyPopen(cmdstring, tm, POPEN_3);
2235
2236 return f;
2237}
2238
2239/*
2240 * Variation on win32pipe.popen
2241 *
2242 * The result of this function is 2 pipes - the processes stdin,
2243 * and stdout+stderr combined as a single pipe.
2244 */
2245
2246static PyObject *
2247win32_popen4(PyObject *self, PyObject *args)
2248{
2249 PyObject *f;
2250 int tm = 0;
2251
2252 char *cmdstring;
2253 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002254 int bufsize = -1;
2255 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002256 return NULL;
2257
2258 if (*mode == 't')
2259 tm = _O_TEXT;
2260 else if (*mode != 'b') {
2261 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2262 return NULL;
2263 } else
2264 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002265
2266 if (bufsize != -1) {
2267 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2268 return NULL;
2269 }
2270
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002271 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002272
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002273 return f;
2274}
2275
2276static int
Mark Hammondb37a3732000-08-14 04:47:33 +00002277_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002278 HANDLE hStdin,
2279 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002280 HANDLE hStderr,
2281 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002282{
2283 PROCESS_INFORMATION piProcInfo;
2284 STARTUPINFO siStartInfo;
2285 char *s1,*s2, *s3 = " /c ";
2286 const char *szConsoleSpawn = "w9xpopen.exe \"";
2287 int i;
2288 int x;
2289
2290 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2291 s1 = (char *)_alloca(i);
2292 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2293 return x;
2294 if (GetVersion() < 0x80000000) {
2295 /*
2296 * NT/2000
2297 */
2298 x = i + strlen(s3) + strlen(cmdstring) + 1;
2299 s2 = (char *)_alloca(x);
2300 ZeroMemory(s2, x);
2301 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2302 }
2303 else {
2304 /*
2305 * Oh gag, we're on Win9x. Use the workaround listed in
2306 * KB: Q150956
2307 */
2308 char modulepath[256];
2309 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2310 for (i = x = 0; modulepath[i]; i++)
2311 if (modulepath[i] == '\\')
2312 x = i+1;
2313 modulepath[x] = '\0';
2314 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2315 strlen(modulepath) +
2316 strlen(szConsoleSpawn) + 1;
2317 s2 = (char *)_alloca(x);
2318 ZeroMemory(s2, x);
2319 sprintf(
2320 s2,
2321 "%s%s%s%s%s\"",
2322 modulepath,
2323 szConsoleSpawn,
2324 s1,
2325 s3,
2326 cmdstring);
2327 }
2328 }
2329
2330 /* Could be an else here to try cmd.exe / command.com in the path
2331 Now we'll just error out.. */
2332 else
2333 return -1;
2334
2335 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2336 siStartInfo.cb = sizeof(STARTUPINFO);
2337 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2338 siStartInfo.hStdInput = hStdin;
2339 siStartInfo.hStdOutput = hStdout;
2340 siStartInfo.hStdError = hStderr;
2341 siStartInfo.wShowWindow = SW_HIDE;
2342
2343 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002344 s2,
2345 NULL,
2346 NULL,
2347 TRUE,
2348 CREATE_NEW_CONSOLE,
2349 NULL,
2350 NULL,
2351 &siStartInfo,
2352 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002353 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002354 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002355
Mark Hammondb37a3732000-08-14 04:47:33 +00002356 /* Return process handle */
2357 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002358 return TRUE;
2359 }
2360 return FALSE;
2361}
2362
2363/* The following code is based off of KB: Q190351 */
2364
2365static PyObject *
2366_PyPopen(char *cmdstring, int mode, int n)
2367{
2368 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2369 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002370 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002371
2372 SECURITY_ATTRIBUTES saAttr;
2373 BOOL fSuccess;
2374 int fd1, fd2, fd3;
2375 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002376 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002377 PyObject *f;
2378
2379 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2380 saAttr.bInheritHandle = TRUE;
2381 saAttr.lpSecurityDescriptor = NULL;
2382
2383 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2384 return win32_error("CreatePipe", NULL);
2385
2386 /* Create new output read handle and the input write handle. Set
2387 * the inheritance properties to FALSE. Otherwise, the child inherits
2388 * the these handles; resulting in non-closeable handles to the pipes
2389 * being created. */
2390 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002391 GetCurrentProcess(), &hChildStdinWrDup, 0,
2392 FALSE,
2393 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002394 if (!fSuccess)
2395 return win32_error("DuplicateHandle", NULL);
2396
2397 /* Close the inheritable version of ChildStdin
2398 that we're using. */
2399 CloseHandle(hChildStdinWr);
2400
2401 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2402 return win32_error("CreatePipe", NULL);
2403
2404 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002405 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2406 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002407 if (!fSuccess)
2408 return win32_error("DuplicateHandle", NULL);
2409
2410 /* Close the inheritable version of ChildStdout
2411 that we're using. */
2412 CloseHandle(hChildStdoutRd);
2413
2414 if (n != POPEN_4) {
2415 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2416 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002417 fSuccess = DuplicateHandle(GetCurrentProcess(),
2418 hChildStderrRd,
2419 GetCurrentProcess(),
2420 &hChildStderrRdDup, 0,
2421 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002422 if (!fSuccess)
2423 return win32_error("DuplicateHandle", NULL);
2424 /* Close the inheritable version of ChildStdErr that we're using. */
2425 CloseHandle(hChildStderrRd);
2426 }
2427
2428 switch (n) {
2429 case POPEN_1:
2430 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2431 case _O_WRONLY | _O_TEXT:
2432 /* Case for writing to child Stdin in text mode. */
2433 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2434 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002435 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002436 PyFile_SetBufSize(f, 0);
2437 /* We don't care about these pipes anymore, so close them. */
2438 CloseHandle(hChildStdoutRdDup);
2439 CloseHandle(hChildStderrRdDup);
2440 break;
2441
2442 case _O_RDONLY | _O_TEXT:
2443 /* Case for reading from child Stdout in text mode. */
2444 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2445 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002446 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002447 PyFile_SetBufSize(f, 0);
2448 /* We don't care about these pipes anymore, so close them. */
2449 CloseHandle(hChildStdinWrDup);
2450 CloseHandle(hChildStderrRdDup);
2451 break;
2452
2453 case _O_RDONLY | _O_BINARY:
2454 /* Case for readinig from child Stdout in binary mode. */
2455 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2456 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002457 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002458 PyFile_SetBufSize(f, 0);
2459 /* We don't care about these pipes anymore, so close them. */
2460 CloseHandle(hChildStdinWrDup);
2461 CloseHandle(hChildStderrRdDup);
2462 break;
2463
2464 case _O_WRONLY | _O_BINARY:
2465 /* Case for writing to child Stdin in binary mode. */
2466 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2467 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002468 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002469 PyFile_SetBufSize(f, 0);
2470 /* We don't care about these pipes anymore, so close them. */
2471 CloseHandle(hChildStdoutRdDup);
2472 CloseHandle(hChildStderrRdDup);
2473 break;
2474 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002475 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002476 break;
2477
2478 case POPEN_2:
2479 case POPEN_4:
2480 {
2481 char *m1, *m2;
2482 PyObject *p1, *p2;
2483
2484 if (mode && _O_TEXT) {
2485 m1 = "r";
2486 m2 = "w";
2487 } else {
2488 m1 = "rb";
2489 m2 = "wb";
2490 }
2491
2492 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2493 f1 = _fdopen(fd1, m2);
2494 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2495 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002496 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002497 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002498 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002499 PyFile_SetBufSize(p2, 0);
2500
2501 if (n != 4)
2502 CloseHandle(hChildStderrRdDup);
2503
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002504 f = Py_BuildValue("OO",p1,p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002505 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002506 break;
2507 }
2508
2509 case POPEN_3:
2510 {
2511 char *m1, *m2;
2512 PyObject *p1, *p2, *p3;
2513
2514 if (mode && _O_TEXT) {
2515 m1 = "r";
2516 m2 = "w";
2517 } else {
2518 m1 = "rb";
2519 m2 = "wb";
2520 }
2521
2522 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2523 f1 = _fdopen(fd1, m2);
2524 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2525 f2 = _fdopen(fd2, m1);
2526 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2527 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002528 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002529 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2530 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002531 PyFile_SetBufSize(p1, 0);
2532 PyFile_SetBufSize(p2, 0);
2533 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002534 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002535 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002536 break;
2537 }
2538 }
2539
2540 if (n == POPEN_4) {
2541 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002542 hChildStdinRd,
2543 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002544 hChildStdoutWr,
2545 &hProcess))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002546 return win32_error("CreateProcess", NULL);
2547 }
2548 else {
2549 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002550 hChildStdinRd,
2551 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002552 hChildStderrWr,
2553 &hProcess))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002554 return win32_error("CreateProcess", NULL);
2555 }
2556
Mark Hammondb37a3732000-08-14 04:47:33 +00002557 /*
2558 * Insert the files we've created into the process dictionary
2559 * all referencing the list with the process handle and the
2560 * initial number of files (see description below in _PyPclose).
2561 * Since if _PyPclose later tried to wait on a process when all
2562 * handles weren't closed, it could create a deadlock with the
2563 * child, we spend some energy here to try to ensure that we
2564 * either insert all file handles into the dictionary or none
2565 * at all. It's a little clumsy with the various popen modes
2566 * and variable number of files involved.
2567 */
2568 if (!_PyPopenProcs) {
2569 _PyPopenProcs = PyDict_New();
2570 }
2571
2572 if (_PyPopenProcs) {
2573 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2574 int ins_rc[3];
2575
2576 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2577 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2578
2579 procObj = PyList_New(2);
2580 hProcessObj = PyLong_FromVoidPtr(hProcess);
2581 intObj = PyInt_FromLong(file_count);
2582
2583 if (procObj && hProcessObj && intObj) {
2584 PyList_SetItem(procObj,0,hProcessObj);
2585 PyList_SetItem(procObj,1,intObj);
2586
2587 fileObj[0] = PyLong_FromVoidPtr(f1);
2588 if (fileObj[0]) {
2589 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2590 fileObj[0],
2591 procObj);
2592 }
2593 if (file_count >= 2) {
2594 fileObj[1] = PyLong_FromVoidPtr(f2);
2595 if (fileObj[1]) {
2596 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2597 fileObj[1],
2598 procObj);
2599 }
2600 }
2601 if (file_count >= 3) {
2602 fileObj[2] = PyLong_FromVoidPtr(f3);
2603 if (fileObj[2]) {
2604 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2605 fileObj[2],
2606 procObj);
2607 }
2608 }
2609
2610 if (ins_rc[0] < 0 || !fileObj[0] ||
2611 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2612 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2613 /* Something failed - remove any dictionary
2614 * entries that did make it.
2615 */
2616 if (!ins_rc[0] && fileObj[0]) {
2617 PyDict_DelItem(_PyPopenProcs,
2618 fileObj[0]);
2619 }
2620 if (!ins_rc[1] && fileObj[1]) {
2621 PyDict_DelItem(_PyPopenProcs,
2622 fileObj[1]);
2623 }
2624 if (!ins_rc[2] && fileObj[2]) {
2625 PyDict_DelItem(_PyPopenProcs,
2626 fileObj[2]);
2627 }
2628 }
2629 }
2630
2631 /*
2632 * Clean up our localized references for the dictionary keys
2633 * and value since PyDict_SetItem will Py_INCREF any copies
2634 * that got placed in the dictionary.
2635 */
2636 Py_XDECREF(procObj);
2637 Py_XDECREF(fileObj[0]);
2638 Py_XDECREF(fileObj[1]);
2639 Py_XDECREF(fileObj[2]);
2640 }
2641
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002642 /* Child is launched. Close the parents copy of those pipe
2643 * handles that only the child should have open. You need to
2644 * make sure that no handles to the write end of the output pipe
2645 * are maintained in this process or else the pipe will not close
2646 * when the child process exits and the ReadFile will hang. */
2647
2648 if (!CloseHandle(hChildStdinRd))
2649 return win32_error("CloseHandle", NULL);
2650
2651 if (!CloseHandle(hChildStdoutWr))
2652 return win32_error("CloseHandle", NULL);
2653
2654 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2655 return win32_error("CloseHandle", NULL);
2656
2657 return f;
2658}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002659
2660/*
2661 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2662 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002663 *
2664 * This function uses the _PyPopenProcs dictionary in order to map the
2665 * input file pointer to information about the process that was
2666 * originally created by the popen* call that created the file pointer.
2667 * The dictionary uses the file pointer as a key (with one entry
2668 * inserted for each file returned by the original popen* call) and a
2669 * single list object as the value for all files from a single call.
2670 * The list object contains the Win32 process handle at [0], and a file
2671 * count at [1], which is initialized to the total number of file
2672 * handles using that list.
2673 *
2674 * This function closes whichever handle it is passed, and decrements
2675 * the file count in the dictionary for the process handle pointed to
2676 * by this file. On the last close (when the file count reaches zero),
2677 * this function will wait for the child process and then return its
2678 * exit code as the result of the close() operation. This permits the
2679 * files to be closed in any order - it is always the close() of the
2680 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002681 */
Tim Peters736aa322000-09-01 06:51:24 +00002682
2683 /* RED_FLAG 31-Aug-2000 Tim
2684 * This is always called (today!) between a pair of
2685 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2686 * macros. So the thread running this has no valid thread state, as
2687 * far as Python is concerned. However, this calls some Python API
2688 * functions that cannot be called safely without a valid thread
2689 * state, in particular PyDict_GetItem.
2690 * As a temporary hack (although it may last for years ...), we
2691 * *rely* on not having a valid thread state in this function, in
2692 * order to create our own "from scratch".
2693 * This will deadlock if _PyPclose is ever called by a thread
2694 * holding the global lock.
2695 */
2696
Fredrik Lundh56055a42000-07-23 19:47:12 +00002697static int _PyPclose(FILE *file)
2698{
Fredrik Lundh20318932000-07-26 17:29:12 +00002699 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002700 DWORD exit_code;
2701 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002702 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2703 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002704#ifdef WITH_THREAD
2705 PyInterpreterState* pInterpreterState;
2706 PyThreadState* pThreadState;
2707#endif
2708
Fredrik Lundh20318932000-07-26 17:29:12 +00002709 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002710 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002711 */
2712 result = fclose(file);
2713
Tim Peters736aa322000-09-01 06:51:24 +00002714#ifdef WITH_THREAD
2715 /* Bootstrap a valid thread state into existence. */
2716 pInterpreterState = PyInterpreterState_New();
2717 if (!pInterpreterState) {
2718 /* Well, we're hosed now! We don't have a thread
2719 * state, so can't call a nice error routine, or raise
2720 * an exception. Just die.
2721 */
2722 Py_FatalError("unable to allocate interpreter state "
Tim Peters9acdd3a2000-09-01 19:26:36 +00002723 "when closing popen object.");
Tim Peters736aa322000-09-01 06:51:24 +00002724 return -1; /* unreachable */
2725 }
2726 pThreadState = PyThreadState_New(pInterpreterState);
2727 if (!pThreadState) {
2728 Py_FatalError("unable to allocate thread state "
Tim Peters9acdd3a2000-09-01 19:26:36 +00002729 "when closing popen object.");
Tim Peters736aa322000-09-01 06:51:24 +00002730 return -1; /* unreachable */
2731 }
2732 /* Grab the global lock. Note that this will deadlock if the
2733 * current thread already has the lock! (see RED_FLAG comments
2734 * before this function)
2735 */
2736 PyEval_RestoreThread(pThreadState);
2737#endif
2738
Fredrik Lundh56055a42000-07-23 19:47:12 +00002739 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002740 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2741 (procObj = PyDict_GetItem(_PyPopenProcs,
2742 fileObj)) != NULL &&
2743 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2744 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2745
2746 hProcess = PyLong_AsVoidPtr(hProcessObj);
2747 file_count = PyInt_AsLong(intObj);
2748
2749 if (file_count > 1) {
2750 /* Still other files referencing process */
2751 file_count--;
2752 PyList_SetItem(procObj,1,
2753 PyInt_FromLong(file_count));
2754 } else {
2755 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002756 if (result != EOF &&
2757 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2758 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002759 /* Possible truncation here in 16-bit environments, but
2760 * real exit codes are just the lower byte in any event.
2761 */
2762 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002763 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002764 /* Indicate failure - this will cause the file object
2765 * to raise an I/O error and translate the last Win32
2766 * error code from errno. We do have a problem with
2767 * last errors that overlap the normal errno table,
2768 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002769 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002770 if (result != EOF) {
2771 /* If the error wasn't from the fclose(), then
2772 * set errno for the file object error handling.
2773 */
2774 errno = GetLastError();
2775 }
2776 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002777 }
2778
2779 /* Free up the native handle at this point */
2780 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002781 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002782
Mark Hammondb37a3732000-08-14 04:47:33 +00002783 /* Remove this file pointer from dictionary */
2784 PyDict_DelItem(_PyPopenProcs, fileObj);
2785
2786 if (PyDict_Size(_PyPopenProcs) == 0) {
2787 Py_DECREF(_PyPopenProcs);
2788 _PyPopenProcs = NULL;
2789 }
2790
2791 } /* if object retrieval ok */
2792
2793 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002794 } /* if _PyPopenProcs */
2795
Tim Peters736aa322000-09-01 06:51:24 +00002796#ifdef WITH_THREAD
2797 /* Tear down the thread & interpreter states.
2798 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002799 * call the thread clear & delete functions, and indeed insist on
2800 * doing that themselves. The lock must be held during the clear, but
2801 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002802 */
2803 PyInterpreterState_Clear(pInterpreterState);
2804 PyEval_ReleaseThread(pThreadState);
2805 PyInterpreterState_Delete(pInterpreterState);
2806#endif
2807
Fredrik Lundh56055a42000-07-23 19:47:12 +00002808 return result;
2809}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002810
2811#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002813posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002814{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002815 char *name;
2816 char *mode = "r";
2817 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002818 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002819 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002820 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002821 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002822 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002823 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002824 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002825 if (fp == NULL)
2826 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002827 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002828 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002829 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002830 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002831}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002832#endif
2833
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002834#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002836
Guido van Rossumb6775db1994-08-01 11:34:53 +00002837#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002838static char posix_setuid__doc__[] =
2839"setuid(uid) -> None\n\
2840Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002842posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002843{
2844 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002845 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002846 return NULL;
2847 if (setuid(uid) < 0)
2848 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002849 Py_INCREF(Py_None);
2850 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002851}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002852#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002853
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002854
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002855#ifdef HAVE_SETEUID
2856static char posix_seteuid__doc__[] =
2857"seteuid(uid) -> None\n\
2858Set the current process's effective user id.";
2859static PyObject *
2860posix_seteuid (PyObject *self, PyObject *args)
2861{
2862 int euid;
2863 if (!PyArg_ParseTuple(args, "i", &euid)) {
2864 return NULL;
2865 } else if (seteuid(euid) < 0) {
2866 return posix_error();
2867 } else {
2868 Py_INCREF(Py_None);
2869 return Py_None;
2870 }
2871}
2872#endif /* HAVE_SETEUID */
2873
2874#ifdef HAVE_SETEGID
2875static char posix_setegid__doc__[] =
2876"setegid(gid) -> None\n\
2877Set the current process's effective group id.";
2878static PyObject *
2879posix_setegid (PyObject *self, PyObject *args)
2880{
2881 int egid;
2882 if (!PyArg_ParseTuple(args, "i", &egid)) {
2883 return NULL;
2884 } else if (setegid(egid) < 0) {
2885 return posix_error();
2886 } else {
2887 Py_INCREF(Py_None);
2888 return Py_None;
2889 }
2890}
2891#endif /* HAVE_SETEGID */
2892
2893#ifdef HAVE_SETREUID
2894static char posix_setreuid__doc__[] =
2895"seteuid(ruid, euid) -> None\n\
2896Set the current process's real and effective user ids.";
2897static PyObject *
2898posix_setreuid (PyObject *self, PyObject *args)
2899{
2900 int ruid, euid;
2901 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2902 return NULL;
2903 } else if (setreuid(ruid, euid) < 0) {
2904 return posix_error();
2905 } else {
2906 Py_INCREF(Py_None);
2907 return Py_None;
2908 }
2909}
2910#endif /* HAVE_SETREUID */
2911
2912#ifdef HAVE_SETREGID
2913static char posix_setregid__doc__[] =
2914"setegid(rgid, egid) -> None\n\
2915Set the current process's real and effective group ids.";
2916static PyObject *
2917posix_setregid (PyObject *self, PyObject *args)
2918{
2919 int rgid, egid;
2920 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2921 return NULL;
2922 } else if (setregid(rgid, egid) < 0) {
2923 return posix_error();
2924 } else {
2925 Py_INCREF(Py_None);
2926 return Py_None;
2927 }
2928}
2929#endif /* HAVE_SETREGID */
2930
Guido van Rossumb6775db1994-08-01 11:34:53 +00002931#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002932static char posix_setgid__doc__[] =
2933"setgid(gid) -> None\n\
2934Set the current process's group id.";
2935
Barry Warsaw53699e91996-12-10 23:23:01 +00002936static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002937posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002938{
2939 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002940 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002941 return NULL;
2942 if (setgid(gid) < 0)
2943 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002944 Py_INCREF(Py_None);
2945 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002946}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002947#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002949
Guido van Rossumb6775db1994-08-01 11:34:53 +00002950#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002951static char posix_waitpid__doc__[] =
2952"waitpid(pid, options) -> (pid, status)\n\
2953Wait for completion of a give child process.";
2954
Barry Warsaw53699e91996-12-10 23:23:01 +00002955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002956posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002957{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002958 int pid, options;
2959#ifdef UNION_WAIT
2960 union wait status;
2961#define status_i (status.w_status)
2962#else
2963 int status;
2964#define status_i status
2965#endif
2966 status_i = 0;
2967
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002968 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002969 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002970 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002971#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002972 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002973#else
2974 pid = waitpid(pid, &status, options);
2975#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002976 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002977 if (pid == -1)
2978 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002979 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002980 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002981}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002982#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002984
Guido van Rossumad0ee831995-03-01 10:34:45 +00002985#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002986static char posix_wait__doc__[] =
2987"wait() -> (pid, status)\n\
2988Wait for completion of a child process.";
2989
Barry Warsaw53699e91996-12-10 23:23:01 +00002990static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002991posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002992{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002993 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002994#ifdef UNION_WAIT
2995 union wait status;
2996#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002997#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002998 int status;
2999#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003000#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003001 if (!PyArg_ParseTuple(args, ":wait"))
3002 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003003 status_i = 0;
3004 Py_BEGIN_ALLOW_THREADS
3005 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003006 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003007 if (pid == -1)
3008 return posix_error();
3009 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003010 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003011#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003012}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003013#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003014
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003015
3016static char posix_lstat__doc__[] =
3017"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3018Like stat(path), but do not follow symbolic links.";
3019
Barry Warsaw53699e91996-12-10 23:23:01 +00003020static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003021posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003022{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003023#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003024 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003025#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00003026 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003027#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003028}
3029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003030
Guido van Rossumb6775db1994-08-01 11:34:53 +00003031#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003032static char posix_readlink__doc__[] =
3033"readlink(path) -> path\n\
3034Return a string representing the path to which the symbolic link points.";
3035
Barry Warsaw53699e91996-12-10 23:23:01 +00003036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003037posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003038{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003039 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003040 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003041 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003042 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003043 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003044 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003045 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003046 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003047 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003048 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003049 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003050}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003051#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003053
Guido van Rossumb6775db1994-08-01 11:34:53 +00003054#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003055static char posix_symlink__doc__[] =
3056"symlink(src, dst) -> None\n\
3057Create a symbolic link.";
3058
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003060posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003061{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003062 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003063}
3064#endif /* HAVE_SYMLINK */
3065
3066
3067#ifdef HAVE_TIMES
3068#ifndef HZ
3069#define HZ 60 /* Universal constant :-) */
3070#endif /* HZ */
3071
Guido van Rossumd48f2521997-12-05 22:19:34 +00003072#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3073static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003074system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003075{
3076 ULONG value = 0;
3077
3078 Py_BEGIN_ALLOW_THREADS
3079 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3080 Py_END_ALLOW_THREADS
3081
3082 return value;
3083}
3084
3085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003086posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003087{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003088 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003089 return NULL;
3090
3091 /* Currently Only Uptime is Provided -- Others Later */
3092 return Py_BuildValue("ddddd",
3093 (double)0 /* t.tms_utime / HZ */,
3094 (double)0 /* t.tms_stime / HZ */,
3095 (double)0 /* t.tms_cutime / HZ */,
3096 (double)0 /* t.tms_cstime / HZ */,
3097 (double)system_uptime() / 1000);
3098}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003099#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003101posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003102{
3103 struct tms t;
3104 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003105 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003106 return NULL;
3107 errno = 0;
3108 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003109 if (c == (clock_t) -1)
3110 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003111 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003112 (double)t.tms_utime / HZ,
3113 (double)t.tms_stime / HZ,
3114 (double)t.tms_cutime / HZ,
3115 (double)t.tms_cstime / HZ,
3116 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003117}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003118#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003119#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003120
3121
Guido van Rossum87755a21996-09-07 00:59:43 +00003122#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003123#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003125posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003126{
3127 FILETIME create, exit, kernel, user;
3128 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003129 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003130 return NULL;
3131 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003132 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3133 /* The fields of a FILETIME structure are the hi and lo part
3134 of a 64-bit value expressed in 100 nanosecond units.
3135 1e7 is one second in such units; 1e-7 the inverse.
3136 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3137 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003138 return Py_BuildValue(
3139 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003140 (double)(kernel.dwHighDateTime*429.4967296 +
3141 kernel.dwLowDateTime*1e-7),
3142 (double)(user.dwHighDateTime*429.4967296 +
3143 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003144 (double)0,
3145 (double)0,
3146 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003147}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003148#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003149
3150#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003151static char posix_times__doc__[] =
3152"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3153Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003154#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003156
Guido van Rossumb6775db1994-08-01 11:34:53 +00003157#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003158static char posix_setsid__doc__[] =
3159"setsid() -> None\n\
3160Call the system call setsid().";
3161
Barry Warsaw53699e91996-12-10 23:23:01 +00003162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003163posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003164{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003165 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003166 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003167 if (setsid() < 0)
3168 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003169 Py_INCREF(Py_None);
3170 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003171}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003172#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003173
Guido van Rossumb6775db1994-08-01 11:34:53 +00003174#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175static char posix_setpgid__doc__[] =
3176"setpgid(pid, pgrp) -> None\n\
3177Call the system call setpgid().";
3178
Barry Warsaw53699e91996-12-10 23:23:01 +00003179static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003180posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003181{
3182 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003183 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003184 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003185 if (setpgid(pid, pgrp) < 0)
3186 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003187 Py_INCREF(Py_None);
3188 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003189}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003190#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003191
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003192
Guido van Rossumb6775db1994-08-01 11:34:53 +00003193#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003194static char posix_tcgetpgrp__doc__[] =
3195"tcgetpgrp(fd) -> pgid\n\
3196Return the process group associated with the terminal given by a fd.";
3197
Barry Warsaw53699e91996-12-10 23:23:01 +00003198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003199posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003200{
3201 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003202 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003203 return NULL;
3204 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003205 if (pgid < 0)
3206 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003207 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003208}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003209#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003211
Guido van Rossumb6775db1994-08-01 11:34:53 +00003212#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003213static char posix_tcsetpgrp__doc__[] =
3214"tcsetpgrp(fd, pgid) -> None\n\
3215Set the process group associated with the terminal given by a fd.";
3216
Barry Warsaw53699e91996-12-10 23:23:01 +00003217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003218posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003219{
3220 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003221 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003222 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003223 if (tcsetpgrp(fd, pgid) < 0)
3224 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003225 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003226 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003227}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003228#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003229
Guido van Rossum687dd131993-05-17 08:34:16 +00003230/* Functions acting on file descriptors */
3231
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003232static char posix_open__doc__[] =
3233"open(filename, flag [, mode=0777]) -> fd\n\
3234Open a file (for low level IO).";
3235
Barry Warsaw53699e91996-12-10 23:23:01 +00003236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003237posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003238{
3239 char *file;
3240 int flag;
3241 int mode = 0777;
3242 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003243 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3244 return NULL;
3245
Barry Warsaw53699e91996-12-10 23:23:01 +00003246 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003247 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003248 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003249 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003250 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003251 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003252}
3253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003254
3255static char posix_close__doc__[] =
3256"close(fd) -> None\n\
3257Close a file descriptor (for low level IO).";
3258
Barry Warsaw53699e91996-12-10 23:23:01 +00003259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003260posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003261{
3262 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003263 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003264 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003265 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003266 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003267 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003268 if (res < 0)
3269 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003270 Py_INCREF(Py_None);
3271 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003272}
3273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003274
3275static char posix_dup__doc__[] =
3276"dup(fd) -> fd2\n\
3277Return a duplicate of a file descriptor.";
3278
Barry Warsaw53699e91996-12-10 23:23:01 +00003279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003280posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003281{
3282 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003283 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003284 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003285 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003286 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003287 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003288 if (fd < 0)
3289 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003290 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003291}
3292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003293
3294static char posix_dup2__doc__[] =
3295"dup2(fd, fd2) -> None\n\
3296Duplicate file descriptor.";
3297
Barry Warsaw53699e91996-12-10 23:23:01 +00003298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003299posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003300{
3301 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003302 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003303 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003304 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003305 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003306 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003307 if (res < 0)
3308 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003309 Py_INCREF(Py_None);
3310 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003311}
3312
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003313
3314static char posix_lseek__doc__[] =
3315"lseek(fd, pos, how) -> newpos\n\
3316Set the current position of a file descriptor.";
3317
Barry Warsaw53699e91996-12-10 23:23:01 +00003318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003319posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003320{
3321 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003322#ifdef MS_WIN64
3323 LONG_LONG pos, res;
3324#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003325 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003326#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003327 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003328 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003329 return NULL;
3330#ifdef SEEK_SET
3331 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3332 switch (how) {
3333 case 0: how = SEEK_SET; break;
3334 case 1: how = SEEK_CUR; break;
3335 case 2: how = SEEK_END; break;
3336 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003337#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003338
3339#if !defined(HAVE_LARGEFILE_SUPPORT)
3340 pos = PyInt_AsLong(posobj);
3341#else
3342 pos = PyLong_Check(posobj) ?
3343 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3344#endif
3345 if (PyErr_Occurred())
3346 return NULL;
3347
Barry Warsaw53699e91996-12-10 23:23:01 +00003348 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003349#ifdef MS_WIN64
3350 res = _lseeki64(fd, pos, how);
3351#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003352 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003353#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003354 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003355 if (res < 0)
3356 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003357
3358#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003359 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003360#else
3361 return PyLong_FromLongLong(res);
3362#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003363}
3364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003365
3366static char posix_read__doc__[] =
3367"read(fd, buffersize) -> string\n\
3368Read a file descriptor.";
3369
Barry Warsaw53699e91996-12-10 23:23:01 +00003370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003371posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003372{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003373 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003374 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003375 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003376 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003377 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003378 if (buffer == NULL)
3379 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003380 Py_BEGIN_ALLOW_THREADS
3381 n = read(fd, PyString_AsString(buffer), size);
3382 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003383 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003384 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003385 return posix_error();
3386 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003387 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003388 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003389 return buffer;
3390}
3391
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003392
3393static char posix_write__doc__[] =
3394"write(fd, string) -> byteswritten\n\
3395Write a string to a file descriptor.";
3396
Barry Warsaw53699e91996-12-10 23:23:01 +00003397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003398posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003399{
3400 int fd, size;
3401 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003402 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003403 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003404 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003405 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003406 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003407 if (size < 0)
3408 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003409 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003410}
3411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003412
3413static char posix_fstat__doc__[]=
3414"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3415Like stat(), but for an open file descriptor.";
3416
Barry Warsaw53699e91996-12-10 23:23:01 +00003417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003418posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003419{
3420 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003421 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003422 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003423 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003424 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003425 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003426 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003427 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003428 if (res != 0)
3429 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003430
3431 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003432}
3433
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003434
3435static char posix_fdopen__doc__[] =
3436"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3437Return an open file object connected to a file descriptor.";
3438
Barry Warsaw53699e91996-12-10 23:23:01 +00003439static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003440posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003441{
Guido van Rossum687dd131993-05-17 08:34:16 +00003442 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003443 char *mode = "r";
3444 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003445 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003446 PyObject *f;
3447 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003448 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003449
Barry Warsaw53699e91996-12-10 23:23:01 +00003450 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003451 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003452 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003453 if (fp == NULL)
3454 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003455 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003456 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003457 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003458 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003459}
3460
Skip Montanaro1517d842000-07-19 14:34:14 +00003461static char posix_isatty__doc__[] =
3462"isatty(fd) -> Boolean\n\
3463Return true if the file descriptor 'fd' is an open file descriptor\n\
3464connected to a terminal.";
3465
3466static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003467posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003468{
3469 int fd;
3470 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3471 return NULL;
3472 return Py_BuildValue("i", isatty(fd));
3473}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003474
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003475#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003476static char posix_pipe__doc__[] =
3477"pipe() -> (read_end, write_end)\n\
3478Create a pipe.";
3479
Barry Warsaw53699e91996-12-10 23:23:01 +00003480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003481posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003482{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003483#if defined(PYOS_OS2)
3484 HFILE read, write;
3485 APIRET rc;
3486
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003487 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003488 return NULL;
3489
3490 Py_BEGIN_ALLOW_THREADS
3491 rc = DosCreatePipe( &read, &write, 4096);
3492 Py_END_ALLOW_THREADS
3493 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003494 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003495
3496 return Py_BuildValue("(ii)", read, write);
3497#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003498#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003499 int fds[2];
3500 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003501 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003502 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003503 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003504 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003505 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003506 if (res != 0)
3507 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003508 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003509#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003510 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003511 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003512 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003513 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003514 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003515 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003516 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003517 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003518 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003519 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003520 read_fd = _open_osfhandle((intptr_t)read, 0);
3521 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003522 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003523#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003524#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003525}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003526#endif /* HAVE_PIPE */
3527
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003528
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003529#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003530static char posix_mkfifo__doc__[] =
3531"mkfifo(file, [, mode=0666]) -> None\n\
3532Create a FIFO (a POSIX named pipe).";
3533
Barry Warsaw53699e91996-12-10 23:23:01 +00003534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003535posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003536{
3537 char *file;
3538 int mode = 0666;
3539 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003540 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003541 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003542 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003543 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003544 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003545 if (res < 0)
3546 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003547 Py_INCREF(Py_None);
3548 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003549}
3550#endif
3551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003552
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003553#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003554static char posix_ftruncate__doc__[] =
3555"ftruncate(fd, length) -> None\n\
3556Truncate a file to a specified length.";
3557
Barry Warsaw53699e91996-12-10 23:23:01 +00003558static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003559posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003560{
3561 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003562 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003563 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003564 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003565
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003566 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003567 return NULL;
3568
3569#if !defined(HAVE_LARGEFILE_SUPPORT)
3570 length = PyInt_AsLong(lenobj);
3571#else
3572 length = PyLong_Check(lenobj) ?
3573 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3574#endif
3575 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003576 return NULL;
3577
Barry Warsaw53699e91996-12-10 23:23:01 +00003578 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003579 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003580 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003581 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003582 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003583 return NULL;
3584 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003585 Py_INCREF(Py_None);
3586 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003587}
3588#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003589
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003590#ifdef NeXT
3591#define HAVE_PUTENV
3592/* Steve Spicklemire got this putenv from NeXTAnswers */
3593static int
3594putenv(char *newval)
3595{
3596 extern char **environ;
3597
3598 static int firstTime = 1;
3599 char **ep;
3600 char *cp;
3601 int esiz;
3602 char *np;
3603
3604 if (!(np = strchr(newval, '=')))
3605 return 1;
3606 *np = '\0';
3607
3608 /* look it up */
3609 for (ep=environ ; *ep ; ep++)
3610 {
3611 /* this should always be true... */
3612 if (cp = strchr(*ep, '='))
3613 {
3614 *cp = '\0';
3615 if (!strcmp(*ep, newval))
3616 {
3617 /* got it! */
3618 *cp = '=';
3619 break;
3620 }
3621 *cp = '=';
3622 }
3623 else
3624 {
3625 *np = '=';
3626 return 1;
3627 }
3628 }
3629
3630 *np = '=';
3631 if (*ep)
3632 {
3633 /* the string was already there:
3634 just replace it with the new one */
3635 *ep = newval;
3636 return 0;
3637 }
3638
3639 /* expand environ by one */
3640 for (esiz=2, ep=environ ; *ep ; ep++)
3641 esiz++;
3642 if (firstTime)
3643 {
3644 char **epp;
3645 char **newenv;
3646 if (!(newenv = malloc(esiz * sizeof(char *))))
3647 return 1;
3648
3649 for (ep=environ, epp=newenv ; *ep ;)
3650 *epp++ = *ep++;
3651 *epp++ = newval;
3652 *epp = (char *) 0;
3653 environ = newenv;
3654 }
3655 else
3656 {
3657 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3658 return 1;
3659 environ[esiz - 2] = newval;
3660 environ[esiz - 1] = (char *) 0;
3661 firstTime = 0;
3662 }
3663
3664 return 0;
3665}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003666#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003668
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003669#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003670static char posix_putenv__doc__[] =
3671"putenv(key, value) -> None\n\
3672Change or add an environment variable.";
3673
Fred Drake762e2061999-08-26 17:23:54 +00003674/* Save putenv() parameters as values here, so we can collect them when they
3675 * get re-set with another call for the same key. */
3676static PyObject *posix_putenv_garbage;
3677
Barry Warsaw53699e91996-12-10 23:23:01 +00003678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003679posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003680{
3681 char *s1, *s2;
3682 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003683 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003684
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003685 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003686 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003687
3688#if defined(PYOS_OS2)
3689 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3690 APIRET rc;
3691
3692 if (strlen(s2) == 0) /* If New Value is an Empty String */
3693 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3694
3695 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3696 if (rc != NO_ERROR)
3697 return os2_error(rc);
3698
3699 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3700 APIRET rc;
3701
3702 if (strlen(s2) == 0) /* If New Value is an Empty String */
3703 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3704
3705 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3706 if (rc != NO_ERROR)
3707 return os2_error(rc);
3708 } else {
3709#endif
3710
Fred Drake762e2061999-08-26 17:23:54 +00003711 /* XXX This can leak memory -- not easy to fix :-( */
3712 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3713 if (newstr == NULL)
3714 return PyErr_NoMemory();
3715 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003716 (void) sprintf(new, "%s=%s", s1, s2);
3717 if (putenv(new)) {
3718 posix_error();
3719 return NULL;
3720 }
Fred Drake762e2061999-08-26 17:23:54 +00003721 /* Install the first arg and newstr in posix_putenv_garbage;
3722 * this will cause previous value to be collected. This has to
3723 * happen after the real putenv() call because the old value
3724 * was still accessible until then. */
3725 if (PyDict_SetItem(posix_putenv_garbage,
3726 PyTuple_GET_ITEM(args, 0), newstr)) {
3727 /* really not much we can do; just leak */
3728 PyErr_Clear();
3729 }
3730 else {
3731 Py_DECREF(newstr);
3732 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003733
3734#if defined(PYOS_OS2)
3735 }
3736#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003737 Py_INCREF(Py_None);
3738 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003739}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003740#endif /* putenv */
3741
3742#ifdef HAVE_STRERROR
3743static char posix_strerror__doc__[] =
3744"strerror(code) -> string\n\
3745Translate an error code to a message string.";
3746
3747PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003748posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003749{
3750 int code;
3751 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003752 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003753 return NULL;
3754 message = strerror(code);
3755 if (message == NULL) {
3756 PyErr_SetString(PyExc_ValueError,
3757 "strerror code out of range");
3758 return NULL;
3759 }
3760 return PyString_FromString(message);
3761}
3762#endif /* strerror */
3763
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003764
Guido van Rossumc9641791998-08-04 15:26:23 +00003765#ifdef HAVE_SYS_WAIT_H
3766
3767#ifdef WIFSTOPPED
3768static char posix_WIFSTOPPED__doc__[] =
3769"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003770Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003771
3772static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003773posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003774{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003775#ifdef UNION_WAIT
3776 union wait status;
3777#define status_i (status.w_status)
3778#else
3779 int status;
3780#define status_i status
3781#endif
3782 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003783
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003784 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003785 {
3786 return NULL;
3787 }
3788
3789 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003790#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003791}
3792#endif /* WIFSTOPPED */
3793
3794#ifdef WIFSIGNALED
3795static char posix_WIFSIGNALED__doc__[] =
3796"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003797Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003798
3799static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003800posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003801{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003802#ifdef UNION_WAIT
3803 union wait status;
3804#define status_i (status.w_status)
3805#else
3806 int status;
3807#define status_i status
3808#endif
3809 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003810
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003811 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003812 {
3813 return NULL;
3814 }
3815
3816 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003817#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003818}
3819#endif /* WIFSIGNALED */
3820
3821#ifdef WIFEXITED
3822static char posix_WIFEXITED__doc__[] =
3823"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003824Return true if the process returning 'status' exited using the exit()\n\
3825system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003826
3827static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003828posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003829{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003830#ifdef UNION_WAIT
3831 union wait status;
3832#define status_i (status.w_status)
3833#else
3834 int status;
3835#define status_i status
3836#endif
3837 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003838
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003839 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003840 {
3841 return NULL;
3842 }
3843
3844 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003845#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003846}
3847#endif /* WIFEXITED */
3848
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003849#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003850static char posix_WEXITSTATUS__doc__[] =
3851"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003852Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003853
3854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003855posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003856{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003857#ifdef UNION_WAIT
3858 union wait status;
3859#define status_i (status.w_status)
3860#else
3861 int status;
3862#define status_i status
3863#endif
3864 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003865
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003866 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003867 {
3868 return NULL;
3869 }
3870
3871 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003872#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003873}
3874#endif /* WEXITSTATUS */
3875
3876#ifdef WTERMSIG
3877static char posix_WTERMSIG__doc__[] =
3878"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003879Return the signal that terminated the process that provided the 'status'\n\
3880value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003881
3882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003883posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003884{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003885#ifdef UNION_WAIT
3886 union wait status;
3887#define status_i (status.w_status)
3888#else
3889 int status;
3890#define status_i status
3891#endif
3892 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003893
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003894 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003895 {
3896 return NULL;
3897 }
3898
3899 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003900#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003901}
3902#endif /* WTERMSIG */
3903
3904#ifdef WSTOPSIG
3905static char posix_WSTOPSIG__doc__[] =
3906"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003907Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003908
3909static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003910posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003911{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003912#ifdef UNION_WAIT
3913 union wait status;
3914#define status_i (status.w_status)
3915#else
3916 int status;
3917#define status_i status
3918#endif
3919 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003920
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003921 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003922 {
3923 return NULL;
3924 }
3925
3926 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003927#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003928}
3929#endif /* WSTOPSIG */
3930
3931#endif /* HAVE_SYS_WAIT_H */
3932
3933
Guido van Rossum94f6f721999-01-06 18:42:14 +00003934#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003935#ifdef _SCO_DS
3936/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3937 needed definitions in sys/statvfs.h */
3938#define _SVID3
3939#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003940#include <sys/statvfs.h>
3941
3942static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003943"fstatvfs(fd) -> \n\
3944 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003945Perform an fstatvfs system call on the given fd.";
3946
3947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003948posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003949{
3950 int fd, res;
3951 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003952 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003953 return NULL;
3954 Py_BEGIN_ALLOW_THREADS
3955 res = fstatvfs(fd, &st);
3956 Py_END_ALLOW_THREADS
3957 if (res != 0)
3958 return posix_error();
3959#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003960 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003961 (long) st.f_bsize,
3962 (long) st.f_frsize,
3963 (long) st.f_blocks,
3964 (long) st.f_bfree,
3965 (long) st.f_bavail,
3966 (long) st.f_files,
3967 (long) st.f_ffree,
3968 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003969 (long) st.f_flag,
3970 (long) st.f_namemax);
3971#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003972 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003973 (long) st.f_bsize,
3974 (long) st.f_frsize,
3975 (LONG_LONG) st.f_blocks,
3976 (LONG_LONG) st.f_bfree,
3977 (LONG_LONG) st.f_bavail,
3978 (LONG_LONG) st.f_files,
3979 (LONG_LONG) st.f_ffree,
3980 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003981 (long) st.f_flag,
3982 (long) st.f_namemax);
3983#endif
3984}
3985#endif /* HAVE_FSTATVFS */
3986
3987
3988#if defined(HAVE_STATVFS)
3989#include <sys/statvfs.h>
3990
3991static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003992"statvfs(path) -> \n\
3993 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003994Perform a statvfs system call on the given path.";
3995
3996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003997posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003998{
3999 char *path;
4000 int res;
4001 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004002 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004003 return NULL;
4004 Py_BEGIN_ALLOW_THREADS
4005 res = statvfs(path, &st);
4006 Py_END_ALLOW_THREADS
4007 if (res != 0)
4008 return posix_error_with_filename(path);
4009#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004010 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004011 (long) st.f_bsize,
4012 (long) st.f_frsize,
4013 (long) st.f_blocks,
4014 (long) st.f_bfree,
4015 (long) st.f_bavail,
4016 (long) st.f_files,
4017 (long) st.f_ffree,
4018 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004019 (long) st.f_flag,
4020 (long) st.f_namemax);
4021#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004022 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004023 (long) st.f_bsize,
4024 (long) st.f_frsize,
4025 (LONG_LONG) st.f_blocks,
4026 (LONG_LONG) st.f_bfree,
4027 (LONG_LONG) st.f_bavail,
4028 (LONG_LONG) st.f_files,
4029 (LONG_LONG) st.f_ffree,
4030 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004031 (long) st.f_flag,
4032 (long) st.f_namemax);
4033#endif
4034}
4035#endif /* HAVE_STATVFS */
4036
4037
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004038#ifdef HAVE_TEMPNAM
4039static char posix_tempnam__doc__[] = "\
4040tempnam([dir[, prefix]]) -> string\n\
4041Return a unique name for a temporary file.\n\
4042The directory and a short may be specified as strings; they may be omitted\n\
4043or None if not needed.";
4044
4045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004046posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004047{
4048 PyObject *result = NULL;
4049 char *dir = NULL;
4050 char *pfx = NULL;
4051 char *name;
4052
4053 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4054 return NULL;
4055 name = tempnam(dir, pfx);
4056 if (name == NULL)
4057 return PyErr_NoMemory();
4058 result = PyString_FromString(name);
4059 free(name);
4060 return result;
4061}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004062#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004063
4064
4065#ifdef HAVE_TMPFILE
4066static char posix_tmpfile__doc__[] = "\
4067tmpfile() -> file object\n\
4068Create a temporary file with no directory entries.";
4069
4070static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004071posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004072{
4073 FILE *fp;
4074
4075 if (!PyArg_ParseTuple(args, ":tmpfile"))
4076 return NULL;
4077 fp = tmpfile();
4078 if (fp == NULL)
4079 return posix_error();
4080 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4081}
4082#endif
4083
4084
4085#ifdef HAVE_TMPNAM
4086static char posix_tmpnam__doc__[] = "\
4087tmpnam() -> string\n\
4088Return a unique name for a temporary file.";
4089
4090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004091posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004092{
4093 char buffer[L_tmpnam];
4094 char *name;
4095
4096 if (!PyArg_ParseTuple(args, ":tmpnam"))
4097 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004098#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004099 name = tmpnam_r(buffer);
4100#else
4101 name = tmpnam(buffer);
4102#endif
4103 if (name == NULL) {
4104 PyErr_SetObject(PyExc_OSError,
4105 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004106#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004107 "unexpected NULL from tmpnam_r"
4108#else
4109 "unexpected NULL from tmpnam"
4110#endif
4111 ));
4112 return NULL;
4113 }
4114 return PyString_FromString(buffer);
4115}
4116#endif
4117
4118
Fred Drakec9680921999-12-13 16:37:25 +00004119/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4120 * It maps strings representing configuration variable names to
4121 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004122 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004123 * rarely-used constants. There are three separate tables that use
4124 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004125 *
4126 * This code is always included, even if none of the interfaces that
4127 * need it are included. The #if hackery needed to avoid it would be
4128 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004129 */
4130struct constdef {
4131 char *name;
4132 long value;
4133};
4134
Fred Drake12c6e2d1999-12-14 21:25:03 +00004135static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004136conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4137 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004138{
4139 if (PyInt_Check(arg)) {
4140 *valuep = PyInt_AS_LONG(arg);
4141 return 1;
4142 }
4143 if (PyString_Check(arg)) {
4144 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004145 size_t lo = 0;
4146 size_t mid;
4147 size_t hi = tablesize;
4148 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004149 char *confname = PyString_AS_STRING(arg);
4150 while (lo < hi) {
4151 mid = (lo + hi) / 2;
4152 cmp = strcmp(confname, table[mid].name);
4153 if (cmp < 0)
4154 hi = mid;
4155 else if (cmp > 0)
4156 lo = mid + 1;
4157 else {
4158 *valuep = table[mid].value;
4159 return 1;
4160 }
4161 }
4162 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4163 }
4164 else
4165 PyErr_SetString(PyExc_TypeError,
4166 "configuration names must be strings or integers");
4167 return 0;
4168}
4169
4170
4171#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4172static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004173#ifdef _PC_ABI_AIO_XFER_MAX
4174 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4175#endif
4176#ifdef _PC_ABI_ASYNC_IO
4177 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4178#endif
Fred Drakec9680921999-12-13 16:37:25 +00004179#ifdef _PC_ASYNC_IO
4180 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4181#endif
4182#ifdef _PC_CHOWN_RESTRICTED
4183 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4184#endif
4185#ifdef _PC_FILESIZEBITS
4186 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4187#endif
4188#ifdef _PC_LAST
4189 {"PC_LAST", _PC_LAST},
4190#endif
4191#ifdef _PC_LINK_MAX
4192 {"PC_LINK_MAX", _PC_LINK_MAX},
4193#endif
4194#ifdef _PC_MAX_CANON
4195 {"PC_MAX_CANON", _PC_MAX_CANON},
4196#endif
4197#ifdef _PC_MAX_INPUT
4198 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4199#endif
4200#ifdef _PC_NAME_MAX
4201 {"PC_NAME_MAX", _PC_NAME_MAX},
4202#endif
4203#ifdef _PC_NO_TRUNC
4204 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4205#endif
4206#ifdef _PC_PATH_MAX
4207 {"PC_PATH_MAX", _PC_PATH_MAX},
4208#endif
4209#ifdef _PC_PIPE_BUF
4210 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4211#endif
4212#ifdef _PC_PRIO_IO
4213 {"PC_PRIO_IO", _PC_PRIO_IO},
4214#endif
4215#ifdef _PC_SOCK_MAXBUF
4216 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4217#endif
4218#ifdef _PC_SYNC_IO
4219 {"PC_SYNC_IO", _PC_SYNC_IO},
4220#endif
4221#ifdef _PC_VDISABLE
4222 {"PC_VDISABLE", _PC_VDISABLE},
4223#endif
4224};
4225
Fred Drakec9680921999-12-13 16:37:25 +00004226static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004227conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004228{
4229 return conv_confname(arg, valuep, posix_constants_pathconf,
4230 sizeof(posix_constants_pathconf)
4231 / sizeof(struct constdef));
4232}
4233#endif
4234
4235#ifdef HAVE_FPATHCONF
4236static char posix_fpathconf__doc__[] = "\
4237fpathconf(fd, name) -> integer\n\
4238Return the configuration limit name for the file descriptor fd.\n\
4239If there is no limit, return -1.";
4240
4241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004242posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004243{
4244 PyObject *result = NULL;
4245 int name, fd;
4246
Fred Drake12c6e2d1999-12-14 21:25:03 +00004247 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4248 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004249 long limit;
4250
4251 errno = 0;
4252 limit = fpathconf(fd, name);
4253 if (limit == -1 && errno != 0)
4254 posix_error();
4255 else
4256 result = PyInt_FromLong(limit);
4257 }
4258 return result;
4259}
4260#endif
4261
4262
4263#ifdef HAVE_PATHCONF
4264static char posix_pathconf__doc__[] = "\
4265pathconf(path, name) -> integer\n\
4266Return the configuration limit name for the file or directory path.\n\
4267If there is no limit, return -1.";
4268
4269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004270posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004271{
4272 PyObject *result = NULL;
4273 int name;
4274 char *path;
4275
4276 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4277 conv_path_confname, &name)) {
4278 long limit;
4279
4280 errno = 0;
4281 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004282 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004283 if (errno == EINVAL)
4284 /* could be a path or name problem */
4285 posix_error();
4286 else
4287 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004288 }
Fred Drakec9680921999-12-13 16:37:25 +00004289 else
4290 result = PyInt_FromLong(limit);
4291 }
4292 return result;
4293}
4294#endif
4295
4296#ifdef HAVE_CONFSTR
4297static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004298#ifdef _CS_ARCHITECTURE
4299 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4300#endif
4301#ifdef _CS_HOSTNAME
4302 {"CS_HOSTNAME", _CS_HOSTNAME},
4303#endif
4304#ifdef _CS_HW_PROVIDER
4305 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4306#endif
4307#ifdef _CS_HW_SERIAL
4308 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4309#endif
4310#ifdef _CS_INITTAB_NAME
4311 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4312#endif
Fred Drakec9680921999-12-13 16:37:25 +00004313#ifdef _CS_LFS64_CFLAGS
4314 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4315#endif
4316#ifdef _CS_LFS64_LDFLAGS
4317 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4318#endif
4319#ifdef _CS_LFS64_LIBS
4320 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4321#endif
4322#ifdef _CS_LFS64_LINTFLAGS
4323 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4324#endif
4325#ifdef _CS_LFS_CFLAGS
4326 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4327#endif
4328#ifdef _CS_LFS_LDFLAGS
4329 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4330#endif
4331#ifdef _CS_LFS_LIBS
4332 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4333#endif
4334#ifdef _CS_LFS_LINTFLAGS
4335 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4336#endif
Fred Draked86ed291999-12-15 15:34:33 +00004337#ifdef _CS_MACHINE
4338 {"CS_MACHINE", _CS_MACHINE},
4339#endif
Fred Drakec9680921999-12-13 16:37:25 +00004340#ifdef _CS_PATH
4341 {"CS_PATH", _CS_PATH},
4342#endif
Fred Draked86ed291999-12-15 15:34:33 +00004343#ifdef _CS_RELEASE
4344 {"CS_RELEASE", _CS_RELEASE},
4345#endif
4346#ifdef _CS_SRPC_DOMAIN
4347 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4348#endif
4349#ifdef _CS_SYSNAME
4350 {"CS_SYSNAME", _CS_SYSNAME},
4351#endif
4352#ifdef _CS_VERSION
4353 {"CS_VERSION", _CS_VERSION},
4354#endif
Fred Drakec9680921999-12-13 16:37:25 +00004355#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4356 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4357#endif
4358#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4359 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4360#endif
4361#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4362 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4363#endif
4364#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4365 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4366#endif
4367#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4368 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4369#endif
4370#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4371 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4372#endif
4373#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4374 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4375#endif
4376#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4377 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4378#endif
4379#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4380 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4381#endif
4382#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4383 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4384#endif
4385#ifdef _CS_XBS5_LP64_OFF64_LIBS
4386 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4387#endif
4388#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4389 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4390#endif
4391#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4392 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4393#endif
4394#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4395 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4396#endif
4397#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4398 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4399#endif
4400#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4401 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4402#endif
Fred Draked86ed291999-12-15 15:34:33 +00004403#ifdef _MIPS_CS_AVAIL_PROCESSORS
4404 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4405#endif
4406#ifdef _MIPS_CS_BASE
4407 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4408#endif
4409#ifdef _MIPS_CS_HOSTID
4410 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4411#endif
4412#ifdef _MIPS_CS_HW_NAME
4413 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4414#endif
4415#ifdef _MIPS_CS_NUM_PROCESSORS
4416 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4417#endif
4418#ifdef _MIPS_CS_OSREL_MAJ
4419 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4420#endif
4421#ifdef _MIPS_CS_OSREL_MIN
4422 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4423#endif
4424#ifdef _MIPS_CS_OSREL_PATCH
4425 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4426#endif
4427#ifdef _MIPS_CS_OS_NAME
4428 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4429#endif
4430#ifdef _MIPS_CS_OS_PROVIDER
4431 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4432#endif
4433#ifdef _MIPS_CS_PROCESSORS
4434 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4435#endif
4436#ifdef _MIPS_CS_SERIAL
4437 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4438#endif
4439#ifdef _MIPS_CS_VENDOR
4440 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4441#endif
Fred Drakec9680921999-12-13 16:37:25 +00004442};
4443
4444static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004445conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004446{
4447 return conv_confname(arg, valuep, posix_constants_confstr,
4448 sizeof(posix_constants_confstr)
4449 / sizeof(struct constdef));
4450}
4451
4452static char posix_confstr__doc__[] = "\
4453confstr(name) -> string\n\
4454Return a string-valued system configuration variable.";
4455
4456static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004457posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004458{
4459 PyObject *result = NULL;
4460 int name;
4461 char buffer[64];
4462
4463 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4464 int len = confstr(name, buffer, sizeof(buffer));
4465
Fred Drakec9680921999-12-13 16:37:25 +00004466 errno = 0;
4467 if (len == 0) {
4468 if (errno != 0)
4469 posix_error();
4470 else
4471 result = PyString_FromString("");
4472 }
4473 else {
4474 if (len >= sizeof(buffer)) {
4475 result = PyString_FromStringAndSize(NULL, len);
4476 if (result != NULL)
4477 confstr(name, PyString_AS_STRING(result), len+1);
4478 }
4479 else
4480 result = PyString_FromString(buffer);
4481 }
4482 }
4483 return result;
4484}
4485#endif
4486
4487
4488#ifdef HAVE_SYSCONF
4489static struct constdef posix_constants_sysconf[] = {
4490#ifdef _SC_2_CHAR_TERM
4491 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4492#endif
4493#ifdef _SC_2_C_BIND
4494 {"SC_2_C_BIND", _SC_2_C_BIND},
4495#endif
4496#ifdef _SC_2_C_DEV
4497 {"SC_2_C_DEV", _SC_2_C_DEV},
4498#endif
4499#ifdef _SC_2_C_VERSION
4500 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4501#endif
4502#ifdef _SC_2_FORT_DEV
4503 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4504#endif
4505#ifdef _SC_2_FORT_RUN
4506 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4507#endif
4508#ifdef _SC_2_LOCALEDEF
4509 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4510#endif
4511#ifdef _SC_2_SW_DEV
4512 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4513#endif
4514#ifdef _SC_2_UPE
4515 {"SC_2_UPE", _SC_2_UPE},
4516#endif
4517#ifdef _SC_2_VERSION
4518 {"SC_2_VERSION", _SC_2_VERSION},
4519#endif
Fred Draked86ed291999-12-15 15:34:33 +00004520#ifdef _SC_ABI_ASYNCHRONOUS_IO
4521 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4522#endif
4523#ifdef _SC_ACL
4524 {"SC_ACL", _SC_ACL},
4525#endif
Fred Drakec9680921999-12-13 16:37:25 +00004526#ifdef _SC_AIO_LISTIO_MAX
4527 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4528#endif
Fred Drakec9680921999-12-13 16:37:25 +00004529#ifdef _SC_AIO_MAX
4530 {"SC_AIO_MAX", _SC_AIO_MAX},
4531#endif
4532#ifdef _SC_AIO_PRIO_DELTA_MAX
4533 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4534#endif
4535#ifdef _SC_ARG_MAX
4536 {"SC_ARG_MAX", _SC_ARG_MAX},
4537#endif
4538#ifdef _SC_ASYNCHRONOUS_IO
4539 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4540#endif
4541#ifdef _SC_ATEXIT_MAX
4542 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4543#endif
Fred Draked86ed291999-12-15 15:34:33 +00004544#ifdef _SC_AUDIT
4545 {"SC_AUDIT", _SC_AUDIT},
4546#endif
Fred Drakec9680921999-12-13 16:37:25 +00004547#ifdef _SC_AVPHYS_PAGES
4548 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4549#endif
4550#ifdef _SC_BC_BASE_MAX
4551 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4552#endif
4553#ifdef _SC_BC_DIM_MAX
4554 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4555#endif
4556#ifdef _SC_BC_SCALE_MAX
4557 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4558#endif
4559#ifdef _SC_BC_STRING_MAX
4560 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4561#endif
Fred Draked86ed291999-12-15 15:34:33 +00004562#ifdef _SC_CAP
4563 {"SC_CAP", _SC_CAP},
4564#endif
Fred Drakec9680921999-12-13 16:37:25 +00004565#ifdef _SC_CHARCLASS_NAME_MAX
4566 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4567#endif
4568#ifdef _SC_CHAR_BIT
4569 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4570#endif
4571#ifdef _SC_CHAR_MAX
4572 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4573#endif
4574#ifdef _SC_CHAR_MIN
4575 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4576#endif
4577#ifdef _SC_CHILD_MAX
4578 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4579#endif
4580#ifdef _SC_CLK_TCK
4581 {"SC_CLK_TCK", _SC_CLK_TCK},
4582#endif
4583#ifdef _SC_COHER_BLKSZ
4584 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4585#endif
4586#ifdef _SC_COLL_WEIGHTS_MAX
4587 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4588#endif
4589#ifdef _SC_DCACHE_ASSOC
4590 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4591#endif
4592#ifdef _SC_DCACHE_BLKSZ
4593 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4594#endif
4595#ifdef _SC_DCACHE_LINESZ
4596 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4597#endif
4598#ifdef _SC_DCACHE_SZ
4599 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4600#endif
4601#ifdef _SC_DCACHE_TBLKSZ
4602 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4603#endif
4604#ifdef _SC_DELAYTIMER_MAX
4605 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4606#endif
4607#ifdef _SC_EQUIV_CLASS_MAX
4608 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4609#endif
4610#ifdef _SC_EXPR_NEST_MAX
4611 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4612#endif
4613#ifdef _SC_FSYNC
4614 {"SC_FSYNC", _SC_FSYNC},
4615#endif
4616#ifdef _SC_GETGR_R_SIZE_MAX
4617 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4618#endif
4619#ifdef _SC_GETPW_R_SIZE_MAX
4620 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4621#endif
4622#ifdef _SC_ICACHE_ASSOC
4623 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4624#endif
4625#ifdef _SC_ICACHE_BLKSZ
4626 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4627#endif
4628#ifdef _SC_ICACHE_LINESZ
4629 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4630#endif
4631#ifdef _SC_ICACHE_SZ
4632 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4633#endif
Fred Draked86ed291999-12-15 15:34:33 +00004634#ifdef _SC_INF
4635 {"SC_INF", _SC_INF},
4636#endif
Fred Drakec9680921999-12-13 16:37:25 +00004637#ifdef _SC_INT_MAX
4638 {"SC_INT_MAX", _SC_INT_MAX},
4639#endif
4640#ifdef _SC_INT_MIN
4641 {"SC_INT_MIN", _SC_INT_MIN},
4642#endif
4643#ifdef _SC_IOV_MAX
4644 {"SC_IOV_MAX", _SC_IOV_MAX},
4645#endif
Fred Draked86ed291999-12-15 15:34:33 +00004646#ifdef _SC_IP_SECOPTS
4647 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4648#endif
Fred Drakec9680921999-12-13 16:37:25 +00004649#ifdef _SC_JOB_CONTROL
4650 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4651#endif
Fred Draked86ed291999-12-15 15:34:33 +00004652#ifdef _SC_KERN_POINTERS
4653 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4654#endif
4655#ifdef _SC_KERN_SIM
4656 {"SC_KERN_SIM", _SC_KERN_SIM},
4657#endif
Fred Drakec9680921999-12-13 16:37:25 +00004658#ifdef _SC_LINE_MAX
4659 {"SC_LINE_MAX", _SC_LINE_MAX},
4660#endif
4661#ifdef _SC_LOGIN_NAME_MAX
4662 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4663#endif
4664#ifdef _SC_LOGNAME_MAX
4665 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4666#endif
4667#ifdef _SC_LONG_BIT
4668 {"SC_LONG_BIT", _SC_LONG_BIT},
4669#endif
Fred Draked86ed291999-12-15 15:34:33 +00004670#ifdef _SC_MAC
4671 {"SC_MAC", _SC_MAC},
4672#endif
Fred Drakec9680921999-12-13 16:37:25 +00004673#ifdef _SC_MAPPED_FILES
4674 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4675#endif
4676#ifdef _SC_MAXPID
4677 {"SC_MAXPID", _SC_MAXPID},
4678#endif
4679#ifdef _SC_MB_LEN_MAX
4680 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4681#endif
4682#ifdef _SC_MEMLOCK
4683 {"SC_MEMLOCK", _SC_MEMLOCK},
4684#endif
4685#ifdef _SC_MEMLOCK_RANGE
4686 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4687#endif
4688#ifdef _SC_MEMORY_PROTECTION
4689 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4690#endif
4691#ifdef _SC_MESSAGE_PASSING
4692 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4693#endif
Fred Draked86ed291999-12-15 15:34:33 +00004694#ifdef _SC_MMAP_FIXED_ALIGNMENT
4695 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4696#endif
Fred Drakec9680921999-12-13 16:37:25 +00004697#ifdef _SC_MQ_OPEN_MAX
4698 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4699#endif
4700#ifdef _SC_MQ_PRIO_MAX
4701 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4702#endif
Fred Draked86ed291999-12-15 15:34:33 +00004703#ifdef _SC_NACLS_MAX
4704 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4705#endif
Fred Drakec9680921999-12-13 16:37:25 +00004706#ifdef _SC_NGROUPS_MAX
4707 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4708#endif
4709#ifdef _SC_NL_ARGMAX
4710 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4711#endif
4712#ifdef _SC_NL_LANGMAX
4713 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4714#endif
4715#ifdef _SC_NL_MSGMAX
4716 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4717#endif
4718#ifdef _SC_NL_NMAX
4719 {"SC_NL_NMAX", _SC_NL_NMAX},
4720#endif
4721#ifdef _SC_NL_SETMAX
4722 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4723#endif
4724#ifdef _SC_NL_TEXTMAX
4725 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4726#endif
4727#ifdef _SC_NPROCESSORS_CONF
4728 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4729#endif
4730#ifdef _SC_NPROCESSORS_ONLN
4731 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4732#endif
Fred Draked86ed291999-12-15 15:34:33 +00004733#ifdef _SC_NPROC_CONF
4734 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4735#endif
4736#ifdef _SC_NPROC_ONLN
4737 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4738#endif
Fred Drakec9680921999-12-13 16:37:25 +00004739#ifdef _SC_NZERO
4740 {"SC_NZERO", _SC_NZERO},
4741#endif
4742#ifdef _SC_OPEN_MAX
4743 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4744#endif
4745#ifdef _SC_PAGESIZE
4746 {"SC_PAGESIZE", _SC_PAGESIZE},
4747#endif
4748#ifdef _SC_PAGE_SIZE
4749 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4750#endif
4751#ifdef _SC_PASS_MAX
4752 {"SC_PASS_MAX", _SC_PASS_MAX},
4753#endif
4754#ifdef _SC_PHYS_PAGES
4755 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4756#endif
4757#ifdef _SC_PII
4758 {"SC_PII", _SC_PII},
4759#endif
4760#ifdef _SC_PII_INTERNET
4761 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4762#endif
4763#ifdef _SC_PII_INTERNET_DGRAM
4764 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4765#endif
4766#ifdef _SC_PII_INTERNET_STREAM
4767 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4768#endif
4769#ifdef _SC_PII_OSI
4770 {"SC_PII_OSI", _SC_PII_OSI},
4771#endif
4772#ifdef _SC_PII_OSI_CLTS
4773 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4774#endif
4775#ifdef _SC_PII_OSI_COTS
4776 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4777#endif
4778#ifdef _SC_PII_OSI_M
4779 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4780#endif
4781#ifdef _SC_PII_SOCKET
4782 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4783#endif
4784#ifdef _SC_PII_XTI
4785 {"SC_PII_XTI", _SC_PII_XTI},
4786#endif
4787#ifdef _SC_POLL
4788 {"SC_POLL", _SC_POLL},
4789#endif
4790#ifdef _SC_PRIORITIZED_IO
4791 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4792#endif
4793#ifdef _SC_PRIORITY_SCHEDULING
4794 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4795#endif
4796#ifdef _SC_REALTIME_SIGNALS
4797 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4798#endif
4799#ifdef _SC_RE_DUP_MAX
4800 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4801#endif
4802#ifdef _SC_RTSIG_MAX
4803 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4804#endif
4805#ifdef _SC_SAVED_IDS
4806 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4807#endif
4808#ifdef _SC_SCHAR_MAX
4809 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4810#endif
4811#ifdef _SC_SCHAR_MIN
4812 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4813#endif
4814#ifdef _SC_SELECT
4815 {"SC_SELECT", _SC_SELECT},
4816#endif
4817#ifdef _SC_SEMAPHORES
4818 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4819#endif
4820#ifdef _SC_SEM_NSEMS_MAX
4821 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4822#endif
4823#ifdef _SC_SEM_VALUE_MAX
4824 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4825#endif
4826#ifdef _SC_SHARED_MEMORY_OBJECTS
4827 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4828#endif
4829#ifdef _SC_SHRT_MAX
4830 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4831#endif
4832#ifdef _SC_SHRT_MIN
4833 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4834#endif
4835#ifdef _SC_SIGQUEUE_MAX
4836 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4837#endif
4838#ifdef _SC_SIGRT_MAX
4839 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4840#endif
4841#ifdef _SC_SIGRT_MIN
4842 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4843#endif
Fred Draked86ed291999-12-15 15:34:33 +00004844#ifdef _SC_SOFTPOWER
4845 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4846#endif
Fred Drakec9680921999-12-13 16:37:25 +00004847#ifdef _SC_SPLIT_CACHE
4848 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4849#endif
4850#ifdef _SC_SSIZE_MAX
4851 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4852#endif
4853#ifdef _SC_STACK_PROT
4854 {"SC_STACK_PROT", _SC_STACK_PROT},
4855#endif
4856#ifdef _SC_STREAM_MAX
4857 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4858#endif
4859#ifdef _SC_SYNCHRONIZED_IO
4860 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4861#endif
4862#ifdef _SC_THREADS
4863 {"SC_THREADS", _SC_THREADS},
4864#endif
4865#ifdef _SC_THREAD_ATTR_STACKADDR
4866 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4867#endif
4868#ifdef _SC_THREAD_ATTR_STACKSIZE
4869 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4870#endif
4871#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4872 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4873#endif
4874#ifdef _SC_THREAD_KEYS_MAX
4875 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4876#endif
4877#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4878 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4879#endif
4880#ifdef _SC_THREAD_PRIO_INHERIT
4881 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4882#endif
4883#ifdef _SC_THREAD_PRIO_PROTECT
4884 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4885#endif
4886#ifdef _SC_THREAD_PROCESS_SHARED
4887 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4888#endif
4889#ifdef _SC_THREAD_SAFE_FUNCTIONS
4890 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4891#endif
4892#ifdef _SC_THREAD_STACK_MIN
4893 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4894#endif
4895#ifdef _SC_THREAD_THREADS_MAX
4896 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4897#endif
4898#ifdef _SC_TIMERS
4899 {"SC_TIMERS", _SC_TIMERS},
4900#endif
4901#ifdef _SC_TIMER_MAX
4902 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4903#endif
4904#ifdef _SC_TTY_NAME_MAX
4905 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4906#endif
4907#ifdef _SC_TZNAME_MAX
4908 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4909#endif
4910#ifdef _SC_T_IOV_MAX
4911 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4912#endif
4913#ifdef _SC_UCHAR_MAX
4914 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4915#endif
4916#ifdef _SC_UINT_MAX
4917 {"SC_UINT_MAX", _SC_UINT_MAX},
4918#endif
4919#ifdef _SC_UIO_MAXIOV
4920 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4921#endif
4922#ifdef _SC_ULONG_MAX
4923 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4924#endif
4925#ifdef _SC_USHRT_MAX
4926 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4927#endif
4928#ifdef _SC_VERSION
4929 {"SC_VERSION", _SC_VERSION},
4930#endif
4931#ifdef _SC_WORD_BIT
4932 {"SC_WORD_BIT", _SC_WORD_BIT},
4933#endif
4934#ifdef _SC_XBS5_ILP32_OFF32
4935 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4936#endif
4937#ifdef _SC_XBS5_ILP32_OFFBIG
4938 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4939#endif
4940#ifdef _SC_XBS5_LP64_OFF64
4941 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4942#endif
4943#ifdef _SC_XBS5_LPBIG_OFFBIG
4944 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4945#endif
4946#ifdef _SC_XOPEN_CRYPT
4947 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4948#endif
4949#ifdef _SC_XOPEN_ENH_I18N
4950 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4951#endif
4952#ifdef _SC_XOPEN_LEGACY
4953 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4954#endif
4955#ifdef _SC_XOPEN_REALTIME
4956 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4957#endif
4958#ifdef _SC_XOPEN_REALTIME_THREADS
4959 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4960#endif
4961#ifdef _SC_XOPEN_SHM
4962 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4963#endif
4964#ifdef _SC_XOPEN_UNIX
4965 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4966#endif
4967#ifdef _SC_XOPEN_VERSION
4968 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4969#endif
4970#ifdef _SC_XOPEN_XCU_VERSION
4971 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4972#endif
4973#ifdef _SC_XOPEN_XPG2
4974 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4975#endif
4976#ifdef _SC_XOPEN_XPG3
4977 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4978#endif
4979#ifdef _SC_XOPEN_XPG4
4980 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4981#endif
4982};
4983
4984static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004985conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004986{
4987 return conv_confname(arg, valuep, posix_constants_sysconf,
4988 sizeof(posix_constants_sysconf)
4989 / sizeof(struct constdef));
4990}
4991
4992static char posix_sysconf__doc__[] = "\
4993sysconf(name) -> integer\n\
4994Return an integer-valued system configuration variable.";
4995
4996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004997posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004998{
4999 PyObject *result = NULL;
5000 int name;
5001
5002 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5003 int value;
5004
5005 errno = 0;
5006 value = sysconf(name);
5007 if (value == -1 && errno != 0)
5008 posix_error();
5009 else
5010 result = PyInt_FromLong(value);
5011 }
5012 return result;
5013}
5014#endif
5015
5016
Fred Drakebec628d1999-12-15 18:31:10 +00005017/* This code is used to ensure that the tables of configuration value names
5018 * are in sorted order as required by conv_confname(), and also to build the
5019 * the exported dictionaries that are used to publish information about the
5020 * names available on the host platform.
5021 *
5022 * Sorting the table at runtime ensures that the table is properly ordered
5023 * when used, even for platforms we're not able to test on. It also makes
5024 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005025 */
Fred Drakebec628d1999-12-15 18:31:10 +00005026
5027static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005028cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005029{
5030 const struct constdef *c1 =
5031 (const struct constdef *) v1;
5032 const struct constdef *c2 =
5033 (const struct constdef *) v2;
5034
5035 return strcmp(c1->name, c2->name);
5036}
5037
5038static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005039setup_confname_table(struct constdef *table, size_t tablesize,
5040 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005041{
Fred Drakebec628d1999-12-15 18:31:10 +00005042 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005043 size_t i;
5044 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005045
5046 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5047 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005048 if (d == NULL)
5049 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005050
Barry Warsaw3155db32000-04-13 15:20:40 +00005051 for (i=0; i < tablesize; ++i) {
5052 PyObject *o = PyInt_FromLong(table[i].value);
5053 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5054 Py_XDECREF(o);
5055 Py_DECREF(d);
5056 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005057 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005058 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005059 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005060 status = PyDict_SetItemString(moddict, tablename, d);
5061 Py_DECREF(d);
5062 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005063}
5064
Fred Drakebec628d1999-12-15 18:31:10 +00005065/* Return -1 on failure, 0 on success. */
5066static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005067setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005068{
5069#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005070 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005071 sizeof(posix_constants_pathconf)
5072 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005073 "pathconf_names", moddict))
5074 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005075#endif
5076#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005077 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005078 sizeof(posix_constants_confstr)
5079 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005080 "confstr_names", moddict))
5081 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005082#endif
5083#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005084 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005085 sizeof(posix_constants_sysconf)
5086 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005087 "sysconf_names", moddict))
5088 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005089#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005090 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005091}
Fred Draked86ed291999-12-15 15:34:33 +00005092
5093
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005094static char posix_abort__doc__[] = "\
5095abort() -> does not return!\n\
5096Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5097in the hardest way possible on the hosting operating system.";
5098
5099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005100posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005101{
5102 if (!PyArg_ParseTuple(args, ":abort"))
5103 return NULL;
5104 abort();
5105 /*NOTREACHED*/
5106 Py_FatalError("abort() called from Python code didn't abort!");
5107 return NULL;
5108}
Fred Drakebec628d1999-12-15 18:31:10 +00005109
Tim Petersf58a7aa2000-09-22 10:05:54 +00005110#ifdef MS_WIN32
5111static char win32_startfile__doc__[] = "\
5112startfile(filepath) - Start a file with its associated application.\n\
5113\n\
5114This acts like double-clicking the file in Explorer, or giving the file\n\
5115name as an argument to the DOS \"start\" command: the file is opened\n\
5116with whatever application (if any) its extension is associated.\n\
5117\n\
5118startfile returns as soon as the associated application is launched.\n\
5119There is no option to wait for the application to close, and no way\n\
5120to retrieve the application's exit status.\n\
5121\n\
5122The filepath is relative to the current directory. If you want to use\n\
5123an absolute path, make sure the first character is not a slash (\"/\");\n\
5124the underlying Win32 ShellExecute function doesn't work if it is.";
5125
5126static PyObject *
5127win32_startfile(PyObject *self, PyObject *args)
5128{
5129 char *filepath;
5130 HINSTANCE rc;
5131 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5132 return NULL;
5133 Py_BEGIN_ALLOW_THREADS
5134 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5135 Py_END_ALLOW_THREADS
5136 if (rc <= (HINSTANCE)32)
5137 return win32_error("startfile", filepath);
5138 Py_INCREF(Py_None);
5139 return Py_None;
5140}
5141#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005142
5143static PyMethodDef posix_methods[] = {
5144 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5145#ifdef HAVE_TTYNAME
5146 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5147#endif
5148 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5149 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005150#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005151 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005152#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005153#ifdef HAVE_CTERMID
5154 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5155#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005156#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005157 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005158#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005159#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005160 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005161#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005162 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5163 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5164 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005165#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005166 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005167#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005168#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005169 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005170#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005171 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5172 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5173 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005174#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005175 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005176#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005177#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005178 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005179#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005180 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005181#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005182 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005183#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005184 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5185 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5186 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005187#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005188 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005189#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005190 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005191#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005192 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5193 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005194#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005195#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005196 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5197 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005198#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005199#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005200 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005201#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005202#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005203 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005204#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005205#ifdef HAVE_FORKPTY
5206 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5207#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005208#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005209 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005210#endif /* HAVE_GETEGID */
5211#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005212 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005213#endif /* HAVE_GETEUID */
5214#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005215 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005216#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005217#ifdef HAVE_GETGROUPS
5218 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5219#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005220 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005221#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005222 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005223#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005224#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005225 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005226#endif /* HAVE_GETPPID */
5227#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005228 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005229#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005230#ifdef HAVE_GETLOGIN
5231 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5232#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005233#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005234 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005235#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005236#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005237 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005238#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005239#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005240 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005241#ifdef MS_WIN32
5242 {"popen2", win32_popen2, METH_VARARGS},
5243 {"popen3", win32_popen3, METH_VARARGS},
5244 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005245 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005246#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005247#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005248#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005249 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005250#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005251#ifdef HAVE_SETEUID
5252 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5253#endif /* HAVE_SETEUID */
5254#ifdef HAVE_SETEGID
5255 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5256#endif /* HAVE_SETEGID */
5257#ifdef HAVE_SETREUID
5258 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5259#endif /* HAVE_SETREUID */
5260#ifdef HAVE_SETREGID
5261 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5262#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005263#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005264 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005265#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005266#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005267 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005268#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005269#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005270 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005271#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005272#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005273 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005274#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005275#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005276 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005277#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005278#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005279 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005280#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005281#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005282 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005283#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005284#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005285 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005286#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005287 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5288 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5289 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5290 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5291 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5292 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5293 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5294 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5295 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005296 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005297#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005298 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005299#endif
5300#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005301 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005302#endif
5303#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005304 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005305#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005306#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005307 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005308#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005309#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005310 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005311#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005312#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005313 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005314#endif
5315#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005316 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005317#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005318#ifdef HAVE_SYS_WAIT_H
5319#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005320 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005321#endif /* WIFSTOPPED */
5322#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005323 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005324#endif /* WIFSIGNALED */
5325#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005326 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005327#endif /* WIFEXITED */
5328#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005329 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005330#endif /* WEXITSTATUS */
5331#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005332 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005333#endif /* WTERMSIG */
5334#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005335 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005336#endif /* WSTOPSIG */
5337#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005338#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005339 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005340#endif
5341#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005342 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005343#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005344#ifdef HAVE_TMPNAM
5345 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5346#endif
5347#ifdef HAVE_TEMPNAM
5348 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5349#endif
5350#ifdef HAVE_TMPNAM
5351 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5352#endif
Fred Drakec9680921999-12-13 16:37:25 +00005353#ifdef HAVE_CONFSTR
5354 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5355#endif
5356#ifdef HAVE_SYSCONF
5357 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5358#endif
5359#ifdef HAVE_FPATHCONF
5360 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5361#endif
5362#ifdef HAVE_PATHCONF
5363 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5364#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005365 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005366 {NULL, NULL} /* Sentinel */
5367};
5368
5369
Barry Warsaw4a342091996-12-19 23:50:02 +00005370static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005371ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005372{
5373 PyObject* v = PyInt_FromLong(value);
5374 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5375 return -1; /* triggers fatal error */
5376
5377 Py_DECREF(v);
5378 return 0;
5379}
5380
Guido van Rossumd48f2521997-12-05 22:19:34 +00005381#if defined(PYOS_OS2)
5382/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5383static int insertvalues(PyObject *d)
5384{
5385 APIRET rc;
5386 ULONG values[QSV_MAX+1];
5387 PyObject *v;
5388 char *ver, tmp[10];
5389
5390 Py_BEGIN_ALLOW_THREADS
5391 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5392 Py_END_ALLOW_THREADS
5393
5394 if (rc != NO_ERROR) {
5395 os2_error(rc);
5396 return -1;
5397 }
5398
5399 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5400 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5401 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5402 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5403 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5404 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5405 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5406
5407 switch (values[QSV_VERSION_MINOR]) {
5408 case 0: ver = "2.00"; break;
5409 case 10: ver = "2.10"; break;
5410 case 11: ver = "2.11"; break;
5411 case 30: ver = "3.00"; break;
5412 case 40: ver = "4.00"; break;
5413 case 50: ver = "5.00"; break;
5414 default:
5415 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5416 values[QSV_VERSION_MINOR]);
5417 ver = &tmp[0];
5418 }
5419
5420 /* Add Indicator of the Version of the Operating System */
5421 v = PyString_FromString(ver);
5422 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5423 return -1;
5424 Py_DECREF(v);
5425
5426 /* Add Indicator of Which Drive was Used to Boot the System */
5427 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5428 tmp[1] = ':';
5429 tmp[2] = '\0';
5430
5431 v = PyString_FromString(tmp);
5432 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5433 return -1;
5434 Py_DECREF(v);
5435
5436 return 0;
5437}
5438#endif
5439
Barry Warsaw4a342091996-12-19 23:50:02 +00005440static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005441all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005442{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005443#ifdef F_OK
5444 if (ins(d, "F_OK", (long)F_OK)) return -1;
5445#endif
5446#ifdef R_OK
5447 if (ins(d, "R_OK", (long)R_OK)) return -1;
5448#endif
5449#ifdef W_OK
5450 if (ins(d, "W_OK", (long)W_OK)) return -1;
5451#endif
5452#ifdef X_OK
5453 if (ins(d, "X_OK", (long)X_OK)) return -1;
5454#endif
Fred Drakec9680921999-12-13 16:37:25 +00005455#ifdef NGROUPS_MAX
5456 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5457#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005458#ifdef TMP_MAX
5459 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5460#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005461#ifdef WNOHANG
5462 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5463#endif
5464#ifdef O_RDONLY
5465 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5466#endif
5467#ifdef O_WRONLY
5468 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5469#endif
5470#ifdef O_RDWR
5471 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5472#endif
5473#ifdef O_NDELAY
5474 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5475#endif
5476#ifdef O_NONBLOCK
5477 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5478#endif
5479#ifdef O_APPEND
5480 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5481#endif
5482#ifdef O_DSYNC
5483 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5484#endif
5485#ifdef O_RSYNC
5486 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5487#endif
5488#ifdef O_SYNC
5489 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5490#endif
5491#ifdef O_NOCTTY
5492 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5493#endif
5494#ifdef O_CREAT
5495 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5496#endif
5497#ifdef O_EXCL
5498 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5499#endif
5500#ifdef O_TRUNC
5501 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5502#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005503#ifdef O_BINARY
5504 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5505#endif
5506#ifdef O_TEXT
5507 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5508#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005509
Guido van Rossum246bc171999-02-01 23:54:31 +00005510#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005511 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5512 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5513 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5514 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5515 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005516#endif
5517
Guido van Rossumd48f2521997-12-05 22:19:34 +00005518#if defined(PYOS_OS2)
5519 if (insertvalues(d)) return -1;
5520#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005521 return 0;
5522}
5523
5524
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005525#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005526#define INITFUNC initnt
5527#define MODNAME "nt"
5528#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005529#if defined(PYOS_OS2)
5530#define INITFUNC initos2
5531#define MODNAME "os2"
5532#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005533#define INITFUNC initposix
5534#define MODNAME "posix"
5535#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005536#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005537
Guido van Rossum3886bb61998-12-04 18:50:17 +00005538DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005539INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005540{
Barry Warsaw53699e91996-12-10 23:23:01 +00005541 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005542
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005543 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005544 posix_methods,
5545 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005546 (PyObject *)NULL,
5547 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005548 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005549
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005550 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005551 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005552 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005553 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005554 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005555
Barry Warsaw4a342091996-12-19 23:50:02 +00005556 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005557 return;
5558
Fred Drakebec628d1999-12-15 18:31:10 +00005559 if (setup_confname_tables(d))
5560 return;
5561
Barry Warsawca74da41999-02-09 19:31:45 +00005562 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005563
Guido van Rossumb3d39562000-01-31 18:41:26 +00005564#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005565 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005566#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005567}