blob: 71a880f997baed8ab846a29de661b97e5d970fb1 [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
705static char posix_fdatasync__doc__[] =
706"fdatasync(fildes) -> None\n\
707force write of file with filedescriptor to disk.\n\
708 does not force update of metadata.";
709
710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000711posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000712{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000713 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000714}
715#endif /* HAVE_FDATASYNC */
716
717
Fredrik Lundh10723342000-07-10 16:38:09 +0000718#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000719static char posix_chown__doc__[] =
720"chown(path, uid, gid) -> None\n\
721Change the owner and group id of path to the numeric uid and gid.";
722
Barry Warsaw53699e91996-12-10 23:23:01 +0000723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000724posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000725{
Fredrik Lundh44328e62000-07-10 15:59:30 +0000726 char *path;
727 int uid, gid;
728 int res;
729 if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
730 return NULL;
731 Py_BEGIN_ALLOW_THREADS
732 res = chown(path, (uid_t) uid, (gid_t) gid);
733 Py_END_ALLOW_THREADS
734 if (res < 0)
735 return posix_error_with_filename(path);
736 Py_INCREF(Py_None);
737 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000738}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000739#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000740
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000741
Guido van Rossum36bc6801995-06-14 22:54:23 +0000742#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000743static char posix_getcwd__doc__[] =
744"getcwd() -> path\n\
745Return a string representing the current working directory.";
746
Barry Warsaw53699e91996-12-10 23:23:01 +0000747static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000748posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000749{
750 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000751 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000752 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000753 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000754 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000755 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000756 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000757 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000758 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000759 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000760}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000761#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000762
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000763
Guido van Rossumb6775db1994-08-01 11:34:53 +0000764#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000765static char posix_link__doc__[] =
766"link(src, dst) -> None\n\
767Create a hard link to a file.";
768
Barry Warsaw53699e91996-12-10 23:23:01 +0000769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000770posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000771{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000772 return posix_2str(args, "ss:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000773}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000774#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000775
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000776
777static char posix_listdir__doc__[] =
778"listdir(path) -> list_of_strings\n\
779Return a list containing the names of the entries in the directory.\n\
780\n\
781 path: path of directory to list\n\
782\n\
783The list is in arbitrary order. It does not include the special\n\
784entries '.' and '..' even if they are present in the directory.";
785
Barry Warsaw53699e91996-12-10 23:23:01 +0000786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000787posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000788{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000789 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000790 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000791#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000792
Guido van Rossumb6775db1994-08-01 11:34:53 +0000793 char *name;
794 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000795 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000796 HANDLE hFindFile;
797 WIN32_FIND_DATA FileData;
798 char namebuf[MAX_PATH+5];
Tim Peters0bb44a42000-09-15 07:44:49 +0000799 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000800
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000801 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000802 return NULL;
803 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000804 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossumb6775db1994-08-01 11:34:53 +0000805 return NULL;
806 }
807 strcpy(namebuf, name);
Tim Peters0bb44a42000-09-15 07:44:49 +0000808 ch = namebuf[len-1];
809 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000810 namebuf[len++] = '/';
811 strcpy(namebuf + len, "*.*");
812
Barry Warsaw53699e91996-12-10 23:23:01 +0000813 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000814 return NULL;
815
816 hFindFile = FindFirstFile(namebuf, &FileData);
817 if (hFindFile == INVALID_HANDLE_VALUE) {
818 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000819 if (errno == ERROR_FILE_NOT_FOUND)
820 return PyList_New(0);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000821 return win32_error("FindFirstFile", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000822 }
823 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000824 if (FileData.cFileName[0] == '.' &&
825 (FileData.cFileName[1] == '\0' ||
826 FileData.cFileName[1] == '.' &&
827 FileData.cFileName[2] == '\0'))
828 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000829 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000830 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000831 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000832 d = NULL;
833 break;
834 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000835 if (PyList_Append(d, v) != 0) {
836 Py_DECREF(v);
837 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000838 d = NULL;
839 break;
840 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000841 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000842 } while (FindNextFile(hFindFile, &FileData) == TRUE);
843
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000844 if (FindClose(hFindFile) == FALSE)
845 return win32_error("FindClose", name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000846
847 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000848
Tim Peters0bb44a42000-09-15 07:44:49 +0000849#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000850
851#ifndef MAX_PATH
852#define MAX_PATH 250
853#endif
854 char *name, *pt;
855 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000856 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000857 char namebuf[MAX_PATH+5];
858 struct _find_t ep;
859
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000860 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000861 return NULL;
862 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000863 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000864 return NULL;
865 }
866 strcpy(namebuf, name);
867 for (pt = namebuf; *pt; pt++)
868 if (*pt == '/')
869 *pt = '\\';
870 if (namebuf[len-1] != '\\')
871 namebuf[len++] = '\\';
872 strcpy(namebuf + len, "*.*");
873
Barry Warsaw53699e91996-12-10 23:23:01 +0000874 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000875 return NULL;
876
877 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000878 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
879 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000880 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000881 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000882 }
883 do {
884 if (ep.name[0] == '.' &&
885 (ep.name[1] == '\0' ||
886 ep.name[1] == '.' &&
887 ep.name[2] == '\0'))
888 continue;
889 strcpy(namebuf, ep.name);
890 for (pt = namebuf; *pt; pt++)
891 if (isupper(*pt))
892 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000893 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000894 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000895 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000896 d = NULL;
897 break;
898 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000899 if (PyList_Append(d, v) != 0) {
900 Py_DECREF(v);
901 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000902 d = NULL;
903 break;
904 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000905 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000906 } while (_dos_findnext(&ep) == 0);
907
908 return d;
909
Tim Peters0bb44a42000-09-15 07:44:49 +0000910#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000911
912#ifndef MAX_PATH
913#define MAX_PATH CCHMAXPATH
914#endif
915 char *name, *pt;
916 int len;
917 PyObject *d, *v;
918 char namebuf[MAX_PATH+5];
919 HDIR hdir = 1;
920 ULONG srchcnt = 1;
921 FILEFINDBUF3 ep;
922 APIRET rc;
923
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000924 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000925 return NULL;
926 if (len >= MAX_PATH) {
927 PyErr_SetString(PyExc_ValueError, "path too long");
928 return NULL;
929 }
930 strcpy(namebuf, name);
931 for (pt = namebuf; *pt; pt++)
932 if (*pt == '/')
933 *pt = '\\';
934 if (namebuf[len-1] != '\\')
935 namebuf[len++] = '\\';
936 strcpy(namebuf + len, "*.*");
937
938 if ((d = PyList_New(0)) == NULL)
939 return NULL;
940
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000941 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
942 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000943 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000944 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
945 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
946 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000947
948 if (rc != NO_ERROR) {
949 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000950 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000951 }
952
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000953 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000954 do {
955 if (ep.achName[0] == '.'
956 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000957 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000958
959 strcpy(namebuf, ep.achName);
960
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000961 /* Leave Case of Name Alone -- In Native Form */
962 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000963
964 v = PyString_FromString(namebuf);
965 if (v == NULL) {
966 Py_DECREF(d);
967 d = NULL;
968 break;
969 }
970 if (PyList_Append(d, v) != 0) {
971 Py_DECREF(v);
972 Py_DECREF(d);
973 d = NULL;
974 break;
975 }
976 Py_DECREF(v);
977 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
978 }
979
980 return d;
981#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000982
Guido van Rossumef0a00e1992-01-27 16:51:30 +0000983 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +0000984 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000986 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000987 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000988 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000989 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000990 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000991 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000992 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000993 closedir(dirp);
994 return NULL;
995 }
996 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000997 if (ep->d_name[0] == '.' &&
998 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +0000999 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001000 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001001 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001002 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001003 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001004 d = NULL;
1005 break;
1006 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001007 if (PyList_Append(d, v) != 0) {
1008 Py_DECREF(v);
1009 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001010 d = NULL;
1011 break;
1012 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001013 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001014 }
1015 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001016
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001017 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001018
Tim Peters0bb44a42000-09-15 07:44:49 +00001019#endif /* which OS */
1020} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001022static char posix_mkdir__doc__[] =
1023"mkdir(path [, mode=0777]) -> None\n\
1024Create a directory.";
1025
Barry Warsaw53699e91996-12-10 23:23:01 +00001026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001027posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001028{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001029 int res;
1030 char *path;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001031 int mode = 0777;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001032 if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001033 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001034 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001035#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001036 res = mkdir(path);
1037#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001038 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001039#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001040 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001041 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001042 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001043 Py_INCREF(Py_None);
1044 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001045}
1046
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001047
Guido van Rossumb6775db1994-08-01 11:34:53 +00001048#ifdef HAVE_NICE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001049static char posix_nice__doc__[] =
1050"nice(inc) -> new_priority\n\
1051Decrease the priority of process and return new priority.";
1052
Barry Warsaw53699e91996-12-10 23:23:01 +00001053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001054posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001055{
1056 int increment, value;
1057
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001058 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001059 return NULL;
1060 value = nice(increment);
1061 if (value == -1)
1062 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001063 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001064}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001065#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001066
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001067
1068static char posix_rename__doc__[] =
1069"rename(old, new) -> None\n\
1070Rename a file or directory.";
1071
Barry Warsaw53699e91996-12-10 23:23:01 +00001072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001073posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001074{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001075 return posix_2str(args, "ss:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001076}
1077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001078
1079static char posix_rmdir__doc__[] =
1080"rmdir(path) -> None\n\
1081Remove a directory.";
1082
Barry Warsaw53699e91996-12-10 23:23:01 +00001083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001084posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001085{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001086 return posix_1str(args, "s:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001087}
1088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001089
1090static char posix_stat__doc__[] =
1091"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1092Perform a stat system call on the given path.";
1093
Barry Warsaw53699e91996-12-10 23:23:01 +00001094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001095posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001096{
Fred Drake699f3522000-06-29 21:12:41 +00001097 return posix_do_stat(self, args, "s:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001098}
1099
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001100
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001101#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001102static char posix_system__doc__[] =
1103"system(command) -> exit_status\n\
1104Execute the command (a string) in a subshell.";
1105
Barry Warsaw53699e91996-12-10 23:23:01 +00001106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001107posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001108{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001109 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001110 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001111 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001112 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001113 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001114 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001115 Py_END_ALLOW_THREADS
1116 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001117}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001118#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001120
1121static char posix_umask__doc__[] =
1122"umask(new_mask) -> old_mask\n\
1123Set the current numeric umask and return the previous umask.";
1124
Barry Warsaw53699e91996-12-10 23:23:01 +00001125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001126posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001127{
1128 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001129 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130 return NULL;
1131 i = umask(i);
1132 if (i < 0)
1133 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001134 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135}
1136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001137
1138static char posix_unlink__doc__[] =
1139"unlink(path) -> None\n\
1140Remove a file (same as remove(path)).";
1141
1142static char posix_remove__doc__[] =
1143"remove(path) -> None\n\
1144Remove a file (same as unlink(path)).";
1145
Barry Warsaw53699e91996-12-10 23:23:01 +00001146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001147posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001148{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001149 return posix_1str(args, "s:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150}
1151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001152
Guido van Rossumb6775db1994-08-01 11:34:53 +00001153#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001154static char posix_uname__doc__[] =
1155"uname() -> (sysname, nodename, release, version, machine)\n\
1156Return a tuple identifying the current operating system.";
1157
Barry Warsaw53699e91996-12-10 23:23:01 +00001158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001159posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001160{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001161 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001162 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001163 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001164 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001165 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001166 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001167 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001168 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001169 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001170 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001171 u.sysname,
1172 u.nodename,
1173 u.release,
1174 u.version,
1175 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001176}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001177#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001179
1180static char posix_utime__doc__[] =
1181"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001182utime(path, None) -> None\n\
1183Set the access and modified time of the file to the given values. If the\n\
1184second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001185
Barry Warsaw53699e91996-12-10 23:23:01 +00001186static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001187posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001188{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001189 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001190 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001191 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001192 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001193
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001194/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001195#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001196 struct utimbuf buf;
1197#define ATIME buf.actime
1198#define MTIME buf.modtime
1199#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001200#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001201 time_t buf[2];
1202#define ATIME buf[0]
1203#define MTIME buf[1]
1204#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001205#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001206
Barry Warsaw3cef8562000-05-01 16:17:24 +00001207 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001208 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001209 if (arg == Py_None) {
1210 /* optional time values not given */
1211 Py_BEGIN_ALLOW_THREADS
1212 res = utime(path, NULL);
1213 Py_END_ALLOW_THREADS
1214 }
1215 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1216 PyErr_SetString(PyExc_TypeError,
1217 "Second argument must be a 2-tuple of numbers.");
1218 return NULL;
1219 }
1220 else {
1221 ATIME = atime;
1222 MTIME = mtime;
1223 Py_BEGIN_ALLOW_THREADS
1224 res = utime(path, UTIME_ARG);
1225 Py_END_ALLOW_THREADS
1226 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001227 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001228 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001229 Py_INCREF(Py_None);
1230 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001231#undef UTIME_ARG
1232#undef ATIME
1233#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001234}
1235
Guido van Rossum85e3b011991-06-03 12:42:10 +00001236
Guido van Rossum3b066191991-06-04 19:40:25 +00001237/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001239static char posix__exit__doc__[] =
1240"_exit(status)\n\
1241Exit to the system with specified status, without normal exit processing.";
1242
Barry Warsaw53699e91996-12-10 23:23:01 +00001243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001244posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001245{
1246 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001247 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001248 return NULL;
1249 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001250 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001251}
1252
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001253
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001254#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001255static char posix_execv__doc__[] =
1256"execv(path, args)\n\
1257Execute an executable path with arguments, replacing current process.\n\
1258\n\
1259 path: path of executable file\n\
1260 args: tuple or list of strings";
1261
Barry Warsaw53699e91996-12-10 23:23:01 +00001262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001263posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001264{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001265 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001266 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001267 char **argvlist;
1268 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001269 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001270
Guido van Rossum89b33251993-10-22 14:26:06 +00001271 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001272 argv is a list or tuple of strings. */
1273
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001274 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001275 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001276 if (PyList_Check(argv)) {
1277 argc = PyList_Size(argv);
1278 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001279 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001280 else if (PyTuple_Check(argv)) {
1281 argc = PyTuple_Size(argv);
1282 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001283 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001284 else {
Guido van Rossum50422b42000-04-26 20:34:28 +00001285 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1286 return NULL;
1287 }
1288
1289 if (argc == 0) {
1290 PyErr_SetString(PyExc_ValueError, "empty argument list");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001291 return NULL;
1292 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001293
Barry Warsaw53699e91996-12-10 23:23:01 +00001294 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001295 if (argvlist == NULL)
1296 return NULL;
1297 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001298 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1299 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001300 PyErr_SetString(PyExc_TypeError,
1301 "all arguments must be strings");
1302 return NULL;
1303
Guido van Rossum85e3b011991-06-03 12:42:10 +00001304 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001305 }
1306 argvlist[argc] = NULL;
1307
Guido van Rossumb6775db1994-08-01 11:34:53 +00001308#ifdef BAD_EXEC_PROTOTYPES
1309 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001310#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001311 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001312#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001313
Guido van Rossum85e3b011991-06-03 12:42:10 +00001314 /* If we get here it's definitely an error */
1315
Barry Warsaw53699e91996-12-10 23:23:01 +00001316 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001317 return posix_error();
1318}
1319
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001320
1321static char posix_execve__doc__[] =
1322"execve(path, args, env)\n\
1323Execute a path with arguments and environment, replacing current process.\n\
1324\n\
1325 path: path of executable file\n\
1326 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001327 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001328
Barry Warsaw53699e91996-12-10 23:23:01 +00001329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001330posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001331{
1332 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001333 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001334 char **argvlist;
1335 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001336 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001337 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001338 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001339
1340 /* execve has three arguments: (path, argv, env), where
1341 argv is a list or tuple of strings and env is a dictionary
1342 like posix.environ. */
1343
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001344 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001345 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001346 if (PyList_Check(argv)) {
1347 argc = PyList_Size(argv);
1348 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001349 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001350 else if (PyTuple_Check(argv)) {
1351 argc = PyTuple_Size(argv);
1352 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001353 }
1354 else {
Barry Warsaw53699e91996-12-10 23:23:01 +00001355 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001356 return NULL;
1357 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001358 if (!PyMapping_Check(env)) {
1359 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001360 return NULL;
1361 }
1362
Guido van Rossum50422b42000-04-26 20:34:28 +00001363 if (argc == 0) {
1364 PyErr_SetString(PyExc_ValueError,
1365 "empty argument list");
1366 return NULL;
1367 }
1368
Barry Warsaw53699e91996-12-10 23:23:01 +00001369 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001370 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001371 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001372 return NULL;
1373 }
1374 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001375 if (!PyArg_Parse((*getitem)(argv, i),
Barry Warsaw43d68b81996-12-19 22:10:44 +00001376 "s;argv must be list of strings",
1377 &argvlist[i]))
1378 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001379 goto fail_1;
1380 }
1381 }
1382 argvlist[argc] = NULL;
1383
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001384 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001385 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001386 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001387 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001388 goto fail_1;
1389 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001390 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001391 keys = PyMapping_Keys(env);
1392 vals = PyMapping_Values(env);
1393 if (!keys || !vals)
1394 goto fail_2;
1395
1396 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001397 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001398
1399 key = PyList_GetItem(keys, pos);
1400 val = PyList_GetItem(vals, pos);
1401 if (!key || !val)
1402 goto fail_2;
1403
Barry Warsaw53699e91996-12-10 23:23:01 +00001404 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
Barry Warsaw43d68b81996-12-19 22:10:44 +00001405 !PyArg_Parse(val, "s;non-string value in env", &v))
1406 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001407 goto fail_2;
1408 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001409
1410#if defined(PYOS_OS2)
1411 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1412 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1413#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001414 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001415 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001416 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001417 goto fail_2;
1418 }
1419 sprintf(p, "%s=%s", k, v);
1420 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001421#if defined(PYOS_OS2)
1422 }
1423#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001424 }
1425 envlist[envc] = 0;
1426
Guido van Rossumb6775db1994-08-01 11:34:53 +00001427
1428#ifdef BAD_EXEC_PROTOTYPES
1429 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001430#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001431 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001432#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001433
1434 /* If we get here it's definitely an error */
1435
1436 (void) posix_error();
1437
1438 fail_2:
1439 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001440 PyMem_DEL(envlist[envc]);
1441 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001442 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001443 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001444 Py_XDECREF(vals);
1445 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001446 return NULL;
1447}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001448#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001449
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001450
Guido van Rossuma1065681999-01-25 23:20:23 +00001451#ifdef HAVE_SPAWNV
1452static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001453"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001454Execute an executable path with arguments, replacing current process.\n\
1455\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001456 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001457 path: path of executable file\n\
1458 args: tuple or list of strings";
1459
1460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001461posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001462{
1463 char *path;
1464 PyObject *argv;
1465 char **argvlist;
1466 int mode, i, argc;
Fred Drake699f3522000-06-29 21:12:41 +00001467 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001468 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001469
1470 /* spawnv has three arguments: (mode, path, argv), where
1471 argv is a list or tuple of strings. */
1472
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001473 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001474 return NULL;
1475 if (PyList_Check(argv)) {
1476 argc = PyList_Size(argv);
1477 getitem = PyList_GetItem;
1478 }
1479 else if (PyTuple_Check(argv)) {
1480 argc = PyTuple_Size(argv);
1481 getitem = PyTuple_GetItem;
1482 }
1483 else {
Fred Drake137507e2000-06-01 02:02:46 +00001484 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001485 return NULL;
1486 }
1487
1488 argvlist = PyMem_NEW(char *, argc+1);
1489 if (argvlist == NULL)
1490 return NULL;
1491 for (i = 0; i < argc; i++) {
1492 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1493 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001494 PyErr_SetString(PyExc_TypeError,
1495 "all arguments must be strings");
1496 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001497 }
1498 }
1499 argvlist[argc] = NULL;
1500
Guido van Rossum246bc171999-02-01 23:54:31 +00001501 if (mode == _OLD_P_OVERLAY)
1502 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001503 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001504
1505 PyMem_DEL(argvlist);
1506
Fred Drake699f3522000-06-29 21:12:41 +00001507 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001508 return posix_error();
1509 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001510#if SIZEOF_LONG == SIZEOF_VOID_P
1511 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001512#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001513 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001514#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001515}
1516
1517
1518static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001519"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001520Execute a path with arguments and environment, replacing current process.\n\
1521\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001522 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001523 path: path of executable file\n\
1524 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001525 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001526
1527static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001528posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001529{
1530 char *path;
1531 PyObject *argv, *env;
1532 char **argvlist;
1533 char **envlist;
1534 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1535 int mode, i, pos, argc, envc;
Fred Drake699f3522000-06-29 21:12:41 +00001536 intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001537 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001538
1539 /* spawnve has four arguments: (mode, path, argv, env), where
1540 argv is a list or tuple of strings and env is a dictionary
1541 like posix.environ. */
1542
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001543 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001544 return NULL;
1545 if (PyList_Check(argv)) {
1546 argc = PyList_Size(argv);
1547 getitem = PyList_GetItem;
1548 }
1549 else if (PyTuple_Check(argv)) {
1550 argc = PyTuple_Size(argv);
1551 getitem = PyTuple_GetItem;
1552 }
1553 else {
1554 PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1555 return NULL;
1556 }
1557 if (!PyMapping_Check(env)) {
1558 PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1559 return NULL;
1560 }
1561
1562 argvlist = PyMem_NEW(char *, argc+1);
1563 if (argvlist == NULL) {
1564 PyErr_NoMemory();
1565 return NULL;
1566 }
1567 for (i = 0; i < argc; i++) {
1568 if (!PyArg_Parse((*getitem)(argv, i),
1569 "s;argv must be list of strings",
1570 &argvlist[i]))
1571 {
1572 goto fail_1;
1573 }
1574 }
1575 argvlist[argc] = NULL;
1576
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001577 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001578 envlist = PyMem_NEW(char *, i + 1);
1579 if (envlist == NULL) {
1580 PyErr_NoMemory();
1581 goto fail_1;
1582 }
1583 envc = 0;
1584 keys = PyMapping_Keys(env);
1585 vals = PyMapping_Values(env);
1586 if (!keys || !vals)
1587 goto fail_2;
1588
1589 for (pos = 0; pos < i; pos++) {
1590 char *p, *k, *v;
1591
1592 key = PyList_GetItem(keys, pos);
1593 val = PyList_GetItem(vals, pos);
1594 if (!key || !val)
1595 goto fail_2;
1596
1597 if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1598 !PyArg_Parse(val, "s;non-string value in env", &v))
1599 {
1600 goto fail_2;
1601 }
1602 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1603 if (p == NULL) {
1604 PyErr_NoMemory();
1605 goto fail_2;
1606 }
1607 sprintf(p, "%s=%s", k, v);
1608 envlist[envc++] = p;
1609 }
1610 envlist[envc] = 0;
1611
Guido van Rossum246bc171999-02-01 23:54:31 +00001612 if (mode == _OLD_P_OVERLAY)
1613 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001614 spawnval = _spawnve(mode, path, argvlist, envlist);
1615 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001616 (void) posix_error();
1617 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001618#if SIZEOF_LONG == SIZEOF_VOID_P
1619 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001620#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001621 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001622#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001623
1624 fail_2:
1625 while (--envc >= 0)
1626 PyMem_DEL(envlist[envc]);
1627 PyMem_DEL(envlist);
1628 fail_1:
1629 PyMem_DEL(argvlist);
1630 Py_XDECREF(vals);
1631 Py_XDECREF(keys);
1632 return res;
1633}
1634#endif /* HAVE_SPAWNV */
1635
1636
Guido van Rossumad0ee831995-03-01 10:34:45 +00001637#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001638static char posix_fork__doc__[] =
1639"fork() -> pid\n\
1640Fork a child process.\n\
1641\n\
1642Return 0 to child process and PID of child to parent process.";
1643
Barry Warsaw53699e91996-12-10 23:23:01 +00001644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001645posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001646{
1647 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001648 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001649 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001650 pid = fork();
1651 if (pid == -1)
1652 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001653 if (pid == 0)
1654 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001655 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001656}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001657#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001658
Fred Drake8cef4cf2000-06-28 16:40:38 +00001659#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1660#ifdef HAVE_PTY_H
1661#include <pty.h>
1662#else
1663#ifdef HAVE_LIBUTIL_H
1664#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001665#endif /* HAVE_LIBUTIL_H */
1666#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001667#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001668
Thomas Wouters70c21a12000-07-14 14:28:33 +00001669#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001670static char posix_openpty__doc__[] =
1671"openpty() -> (master_fd, slave_fd)\n\
1672Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1673
1674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001675posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001676{
1677 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001678#ifndef HAVE_OPENPTY
1679 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001680#endif
1681
Fred Drake8cef4cf2000-06-28 16:40:38 +00001682 if (!PyArg_ParseTuple(args, ":openpty"))
1683 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001684
1685#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001686 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1687 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001688#else
1689 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1690 if (slave_name == NULL)
1691 return posix_error();
1692
1693 slave_fd = open(slave_name, O_RDWR);
1694 if (slave_fd < 0)
1695 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001696#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001697
Fred Drake8cef4cf2000-06-28 16:40:38 +00001698 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001699
Fred Drake8cef4cf2000-06-28 16:40:38 +00001700}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001701#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001702
1703#ifdef HAVE_FORKPTY
1704static char posix_forkpty__doc__[] =
1705"forkpty() -> (pid, master_fd)\n\
1706Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1707Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1708To both, return fd of newly opened pseudo-terminal.\n";
1709
1710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001711posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001712{
1713 int master_fd, pid;
1714
1715 if (!PyArg_ParseTuple(args, ":forkpty"))
1716 return NULL;
1717 pid = forkpty(&master_fd, NULL, NULL, NULL);
1718 if (pid == -1)
1719 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001720 if (pid == 0)
1721 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001722 return Py_BuildValue("(ii)", pid, master_fd);
1723}
1724#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001725
Guido van Rossumad0ee831995-03-01 10:34:45 +00001726#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001727static char posix_getegid__doc__[] =
1728"getegid() -> egid\n\
1729Return the current process's effective group id.";
1730
Barry Warsaw53699e91996-12-10 23:23:01 +00001731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001732posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001733{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001734 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001735 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001736 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001737}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001738#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001739
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001740
Guido van Rossumad0ee831995-03-01 10:34:45 +00001741#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001742static char posix_geteuid__doc__[] =
1743"geteuid() -> euid\n\
1744Return the current process's effective user id.";
1745
Barry Warsaw53699e91996-12-10 23:23:01 +00001746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001747posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001748{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001749 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001750 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001751 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001752}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001753#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001754
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001755
Guido van Rossumad0ee831995-03-01 10:34:45 +00001756#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001757static char posix_getgid__doc__[] =
1758"getgid() -> gid\n\
1759Return the current process's group id.";
1760
Barry Warsaw53699e91996-12-10 23:23:01 +00001761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001762posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001763{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001764 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001765 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001766 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001767}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001768#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001770
1771static char posix_getpid__doc__[] =
1772"getpid() -> pid\n\
1773Return the current process id";
1774
Barry Warsaw53699e91996-12-10 23:23:01 +00001775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001776posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001777{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001778 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001779 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001780 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001781}
1782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001783
Fred Drakec9680921999-12-13 16:37:25 +00001784#ifdef HAVE_GETGROUPS
1785static char posix_getgroups__doc__[] = "\
1786getgroups() -> list of group IDs\n\
1787Return list of supplemental group IDs for the process.";
1788
1789static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001790posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001791{
1792 PyObject *result = NULL;
1793
1794 if (PyArg_ParseTuple(args, ":getgroups")) {
1795#ifdef NGROUPS_MAX
1796#define MAX_GROUPS NGROUPS_MAX
1797#else
1798 /* defined to be 16 on Solaris7, so this should be a small number */
1799#define MAX_GROUPS 64
1800#endif
1801 gid_t grouplist[MAX_GROUPS];
1802 int n;
1803
1804 n = getgroups(MAX_GROUPS, grouplist);
1805 if (n < 0)
1806 posix_error();
1807 else {
1808 result = PyList_New(n);
1809 if (result != NULL) {
1810 PyObject *o;
1811 int i;
1812 for (i = 0; i < n; ++i) {
1813 o = PyInt_FromLong((long)grouplist[i]);
1814 if (o == NULL) {
1815 Py_DECREF(result);
1816 result = NULL;
1817 break;
1818 }
1819 PyList_SET_ITEM(result, i, o);
1820 }
1821 }
1822 }
1823 }
1824 return result;
1825}
1826#endif
1827
Guido van Rossumb6775db1994-08-01 11:34:53 +00001828#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001829static char posix_getpgrp__doc__[] =
1830"getpgrp() -> pgrp\n\
1831Return the current process group id.";
1832
Barry Warsaw53699e91996-12-10 23:23:01 +00001833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001834posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001835{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001836 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001837 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001838#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001839 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001840#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001841 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001842#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001843}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001844#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001845
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001846
Guido van Rossumb6775db1994-08-01 11:34:53 +00001847#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001848static char posix_setpgrp__doc__[] =
1849"setpgrp() -> None\n\
1850Make this process a session leader.";
1851
Barry Warsaw53699e91996-12-10 23:23:01 +00001852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001853posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001854{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001855 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001856 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001857#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001858 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001859#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001860 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001861#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001862 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001863 Py_INCREF(Py_None);
1864 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001865}
1866
Guido van Rossumb6775db1994-08-01 11:34:53 +00001867#endif /* HAVE_SETPGRP */
1868
Guido van Rossumad0ee831995-03-01 10:34:45 +00001869#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001870static char posix_getppid__doc__[] =
1871"getppid() -> ppid\n\
1872Return the parent's process id.";
1873
Barry Warsaw53699e91996-12-10 23:23:01 +00001874static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001875posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001876{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001877 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001878 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001879 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001880}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001881#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001883
Fred Drake12c6e2d1999-12-14 21:25:03 +00001884#ifdef HAVE_GETLOGIN
1885static char posix_getlogin__doc__[] = "\
1886getlogin() -> string\n\
1887Return the actual login name.";
1888
1889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001890posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00001891{
1892 PyObject *result = NULL;
1893
1894 if (PyArg_ParseTuple(args, ":getlogin")) {
1895 char *name = getlogin();
1896
1897 if (name == NULL)
1898 posix_error();
1899 else
1900 result = PyString_FromString(name);
1901 }
1902 return result;
1903}
1904#endif
1905
Guido van Rossumad0ee831995-03-01 10:34:45 +00001906#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001907static char posix_getuid__doc__[] =
1908"getuid() -> uid\n\
1909Return the current process's user id.";
1910
Barry Warsaw53699e91996-12-10 23:23:01 +00001911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001912posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001913{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001914 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001915 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001916 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001917}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001918#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001919
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001920
Guido van Rossumad0ee831995-03-01 10:34:45 +00001921#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001922static char posix_kill__doc__[] =
1923"kill(pid, sig) -> None\n\
1924Kill a process with a signal.";
1925
Barry Warsaw53699e91996-12-10 23:23:01 +00001926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001927posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001928{
1929 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001930 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001931 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001932#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001933 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1934 APIRET rc;
1935 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001936 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001937
1938 } else if (sig == XCPT_SIGNAL_KILLPROC) {
1939 APIRET rc;
1940 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != 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
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001944 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001945#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00001946 if (kill(pid, sig) == -1)
1947 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001948#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001949 Py_INCREF(Py_None);
1950 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001951}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001952#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001953
Guido van Rossumc0125471996-06-28 18:55:32 +00001954#ifdef HAVE_PLOCK
1955
1956#ifdef HAVE_SYS_LOCK_H
1957#include <sys/lock.h>
1958#endif
1959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001960static char posix_plock__doc__[] =
1961"plock(op) -> None\n\
1962Lock program segments into memory.";
1963
Barry Warsaw53699e91996-12-10 23:23:01 +00001964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001965posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00001966{
1967 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001968 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00001969 return NULL;
1970 if (plock(op) == -1)
1971 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001972 Py_INCREF(Py_None);
1973 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00001974}
1975#endif
1976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001977
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001978#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001979static char posix_popen__doc__[] =
1980"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
1981Open a pipe to/from a command returning a file object.";
1982
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001983#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00001984static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001985async_system(const char *command)
1986{
1987 char *p, errormsg[256], args[1024];
1988 RESULTCODES rcodes;
1989 APIRET rc;
1990 char *shell = getenv("COMSPEC");
1991 if (!shell)
1992 shell = "cmd";
1993
1994 strcpy(args, shell);
1995 p = &args[ strlen(args)+1 ];
1996 strcpy(p, "/c ");
1997 strcat(p, command);
1998 p += strlen(p) + 1;
1999 *p = '\0';
2000
2001 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002002 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002003 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002004 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002005 &rcodes, shell);
2006 return rc;
2007}
2008
Guido van Rossumd48f2521997-12-05 22:19:34 +00002009static FILE *
2010popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002011{
2012 HFILE rhan, whan;
2013 FILE *retfd = NULL;
2014 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2015
Guido van Rossumd48f2521997-12-05 22:19:34 +00002016 if (rc != NO_ERROR) {
2017 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002018 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002019 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002020
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002021 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2022 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002023
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002024 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2025 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002026
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002027 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2028 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002029
2030 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002031 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002032 }
2033
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002034 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2035 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002036
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002037 close(oldfd); /* And Close Saved STDOUT Handle */
2038 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002039
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002040 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2041 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002042
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002043 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2044 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002045
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002046 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2047 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002048
2049 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002050 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002051 }
2052
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002053 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2054 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002055
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002056 close(oldfd); /* And Close Saved STDIN Handle */
2057 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002058
Guido van Rossumd48f2521997-12-05 22:19:34 +00002059 } else {
2060 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002061 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002062 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002063}
2064
2065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002066posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002067{
2068 char *name;
2069 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002070 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002071 FILE *fp;
2072 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002073 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074 return NULL;
2075 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002076 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002077 Py_END_ALLOW_THREADS
2078 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002079 return os2_error(err);
2080
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002081 f = PyFile_FromFile(fp, name, mode, fclose);
2082 if (f != NULL)
2083 PyFile_SetBufSize(f, bufsize);
2084 return f;
2085}
2086
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002087#elif defined(MS_WIN32)
2088
2089/*
2090 * Portable 'popen' replacement for Win32.
2091 *
2092 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2093 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002094 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002095 */
2096
2097#include <malloc.h>
2098#include <io.h>
2099#include <fcntl.h>
2100
2101/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2102#define POPEN_1 1
2103#define POPEN_2 2
2104#define POPEN_3 3
2105#define POPEN_4 4
2106
2107static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002108static int _PyPclose(FILE *file);
2109
2110/*
2111 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002112 * for use when retrieving the process exit code. See _PyPclose() below
2113 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002114 */
2115static PyObject *_PyPopenProcs = NULL;
2116
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002117
2118/* popen that works from a GUI.
2119 *
2120 * The result of this function is a pipe (file) connected to the
2121 * processes stdin or stdout, depending on the requested mode.
2122 */
2123
2124static PyObject *
2125posix_popen(PyObject *self, PyObject *args)
2126{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002127 PyObject *f, *s;
2128 int tm = 0;
2129
2130 char *cmdstring;
2131 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002132 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002133 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002134 return NULL;
2135
2136 s = PyTuple_New(0);
2137
2138 if (*mode == 'r')
2139 tm = _O_RDONLY;
2140 else if (*mode != 'w') {
2141 PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2142 return NULL;
2143 } else
2144 tm = _O_WRONLY;
2145
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002146 if (bufsize != -1) {
2147 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2148 return NULL;
2149 }
2150
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002151 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002152 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002153 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002154 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002155 else
2156 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2157
2158 return f;
2159}
2160
2161/* Variation on win32pipe.popen
2162 *
2163 * The result of this function is a pipe (file) connected to the
2164 * process's stdin, and a pipe connected to the process's stdout.
2165 */
2166
2167static PyObject *
2168win32_popen2(PyObject *self, PyObject *args)
2169{
2170 PyObject *f;
2171 int tm=0;
2172
2173 char *cmdstring;
2174 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002175 int bufsize = -1;
2176 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002177 return NULL;
2178
2179 if (*mode == 't')
2180 tm = _O_TEXT;
2181 else if (*mode != 'b') {
2182 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2183 return NULL;
2184 } else
2185 tm = _O_BINARY;
2186
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002187 if (bufsize != -1) {
2188 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2189 return NULL;
2190 }
2191
2192 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002193
2194 return f;
2195}
2196
2197/*
2198 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002199 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002200 * The result of this function is 3 pipes - the process's stdin,
2201 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002202 */
2203
2204static PyObject *
2205win32_popen3(PyObject *self, PyObject *args)
2206{
2207 PyObject *f;
2208 int tm = 0;
2209
2210 char *cmdstring;
2211 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002212 int bufsize = -1;
2213 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002214 return NULL;
2215
2216 if (*mode == 't')
2217 tm = _O_TEXT;
2218 else if (*mode != 'b') {
2219 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2220 return NULL;
2221 } else
2222 tm = _O_BINARY;
2223
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002224 if (bufsize != -1) {
2225 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2226 return NULL;
2227 }
2228
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002229 f = _PyPopen(cmdstring, tm, POPEN_3);
2230
2231 return f;
2232}
2233
2234/*
2235 * Variation on win32pipe.popen
2236 *
2237 * The result of this function is 2 pipes - the processes stdin,
2238 * and stdout+stderr combined as a single pipe.
2239 */
2240
2241static PyObject *
2242win32_popen4(PyObject *self, PyObject *args)
2243{
2244 PyObject *f;
2245 int tm = 0;
2246
2247 char *cmdstring;
2248 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002249 int bufsize = -1;
2250 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002251 return NULL;
2252
2253 if (*mode == 't')
2254 tm = _O_TEXT;
2255 else if (*mode != 'b') {
2256 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2257 return NULL;
2258 } else
2259 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002260
2261 if (bufsize != -1) {
2262 PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2263 return NULL;
2264 }
2265
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002266 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002267
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002268 return f;
2269}
2270
2271static int
Mark Hammondb37a3732000-08-14 04:47:33 +00002272_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002273 HANDLE hStdin,
2274 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002275 HANDLE hStderr,
2276 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002277{
2278 PROCESS_INFORMATION piProcInfo;
2279 STARTUPINFO siStartInfo;
2280 char *s1,*s2, *s3 = " /c ";
2281 const char *szConsoleSpawn = "w9xpopen.exe \"";
2282 int i;
2283 int x;
2284
2285 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2286 s1 = (char *)_alloca(i);
2287 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2288 return x;
2289 if (GetVersion() < 0x80000000) {
2290 /*
2291 * NT/2000
2292 */
2293 x = i + strlen(s3) + strlen(cmdstring) + 1;
2294 s2 = (char *)_alloca(x);
2295 ZeroMemory(s2, x);
2296 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2297 }
2298 else {
2299 /*
2300 * Oh gag, we're on Win9x. Use the workaround listed in
2301 * KB: Q150956
2302 */
2303 char modulepath[256];
2304 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2305 for (i = x = 0; modulepath[i]; i++)
2306 if (modulepath[i] == '\\')
2307 x = i+1;
2308 modulepath[x] = '\0';
2309 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2310 strlen(modulepath) +
2311 strlen(szConsoleSpawn) + 1;
2312 s2 = (char *)_alloca(x);
2313 ZeroMemory(s2, x);
2314 sprintf(
2315 s2,
2316 "%s%s%s%s%s\"",
2317 modulepath,
2318 szConsoleSpawn,
2319 s1,
2320 s3,
2321 cmdstring);
2322 }
2323 }
2324
2325 /* Could be an else here to try cmd.exe / command.com in the path
2326 Now we'll just error out.. */
2327 else
2328 return -1;
2329
2330 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2331 siStartInfo.cb = sizeof(STARTUPINFO);
2332 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2333 siStartInfo.hStdInput = hStdin;
2334 siStartInfo.hStdOutput = hStdout;
2335 siStartInfo.hStdError = hStderr;
2336 siStartInfo.wShowWindow = SW_HIDE;
2337
2338 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002339 s2,
2340 NULL,
2341 NULL,
2342 TRUE,
2343 CREATE_NEW_CONSOLE,
2344 NULL,
2345 NULL,
2346 &siStartInfo,
2347 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002348 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002349 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002350
Mark Hammondb37a3732000-08-14 04:47:33 +00002351 /* Return process handle */
2352 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002353 return TRUE;
2354 }
2355 return FALSE;
2356}
2357
2358/* The following code is based off of KB: Q190351 */
2359
2360static PyObject *
2361_PyPopen(char *cmdstring, int mode, int n)
2362{
2363 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2364 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002365 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002366
2367 SECURITY_ATTRIBUTES saAttr;
2368 BOOL fSuccess;
2369 int fd1, fd2, fd3;
2370 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002371 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002372 PyObject *f;
2373
2374 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2375 saAttr.bInheritHandle = TRUE;
2376 saAttr.lpSecurityDescriptor = NULL;
2377
2378 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2379 return win32_error("CreatePipe", NULL);
2380
2381 /* Create new output read handle and the input write handle. Set
2382 * the inheritance properties to FALSE. Otherwise, the child inherits
2383 * the these handles; resulting in non-closeable handles to the pipes
2384 * being created. */
2385 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002386 GetCurrentProcess(), &hChildStdinWrDup, 0,
2387 FALSE,
2388 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002389 if (!fSuccess)
2390 return win32_error("DuplicateHandle", NULL);
2391
2392 /* Close the inheritable version of ChildStdin
2393 that we're using. */
2394 CloseHandle(hChildStdinWr);
2395
2396 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2397 return win32_error("CreatePipe", NULL);
2398
2399 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002400 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2401 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002402 if (!fSuccess)
2403 return win32_error("DuplicateHandle", NULL);
2404
2405 /* Close the inheritable version of ChildStdout
2406 that we're using. */
2407 CloseHandle(hChildStdoutRd);
2408
2409 if (n != POPEN_4) {
2410 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2411 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002412 fSuccess = DuplicateHandle(GetCurrentProcess(),
2413 hChildStderrRd,
2414 GetCurrentProcess(),
2415 &hChildStderrRdDup, 0,
2416 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002417 if (!fSuccess)
2418 return win32_error("DuplicateHandle", NULL);
2419 /* Close the inheritable version of ChildStdErr that we're using. */
2420 CloseHandle(hChildStderrRd);
2421 }
2422
2423 switch (n) {
2424 case POPEN_1:
2425 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2426 case _O_WRONLY | _O_TEXT:
2427 /* Case for writing to child Stdin in text mode. */
2428 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2429 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002430 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002431 PyFile_SetBufSize(f, 0);
2432 /* We don't care about these pipes anymore, so close them. */
2433 CloseHandle(hChildStdoutRdDup);
2434 CloseHandle(hChildStderrRdDup);
2435 break;
2436
2437 case _O_RDONLY | _O_TEXT:
2438 /* Case for reading from child Stdout in text mode. */
2439 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2440 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002441 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002442 PyFile_SetBufSize(f, 0);
2443 /* We don't care about these pipes anymore, so close them. */
2444 CloseHandle(hChildStdinWrDup);
2445 CloseHandle(hChildStderrRdDup);
2446 break;
2447
2448 case _O_RDONLY | _O_BINARY:
2449 /* Case for readinig from child Stdout in binary mode. */
2450 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2451 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002452 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002453 PyFile_SetBufSize(f, 0);
2454 /* We don't care about these pipes anymore, so close them. */
2455 CloseHandle(hChildStdinWrDup);
2456 CloseHandle(hChildStderrRdDup);
2457 break;
2458
2459 case _O_WRONLY | _O_BINARY:
2460 /* Case for writing to child Stdin in binary mode. */
2461 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2462 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002463 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002464 PyFile_SetBufSize(f, 0);
2465 /* We don't care about these pipes anymore, so close them. */
2466 CloseHandle(hChildStdoutRdDup);
2467 CloseHandle(hChildStderrRdDup);
2468 break;
2469 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002470 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002471 break;
2472
2473 case POPEN_2:
2474 case POPEN_4:
2475 {
2476 char *m1, *m2;
2477 PyObject *p1, *p2;
2478
2479 if (mode && _O_TEXT) {
2480 m1 = "r";
2481 m2 = "w";
2482 } else {
2483 m1 = "rb";
2484 m2 = "wb";
2485 }
2486
2487 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2488 f1 = _fdopen(fd1, m2);
2489 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2490 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002491 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002492 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002493 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002494 PyFile_SetBufSize(p2, 0);
2495
2496 if (n != 4)
2497 CloseHandle(hChildStderrRdDup);
2498
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002499 f = Py_BuildValue("OO",p1,p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002500 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002501 break;
2502 }
2503
2504 case POPEN_3:
2505 {
2506 char *m1, *m2;
2507 PyObject *p1, *p2, *p3;
2508
2509 if (mode && _O_TEXT) {
2510 m1 = "r";
2511 m2 = "w";
2512 } else {
2513 m1 = "rb";
2514 m2 = "wb";
2515 }
2516
2517 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2518 f1 = _fdopen(fd1, m2);
2519 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2520 f2 = _fdopen(fd2, m1);
2521 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2522 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002523 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002524 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2525 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002526 PyFile_SetBufSize(p1, 0);
2527 PyFile_SetBufSize(p2, 0);
2528 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002529 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002530 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002531 break;
2532 }
2533 }
2534
2535 if (n == POPEN_4) {
2536 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002537 hChildStdinRd,
2538 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002539 hChildStdoutWr,
2540 &hProcess))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002541 return win32_error("CreateProcess", NULL);
2542 }
2543 else {
2544 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002545 hChildStdinRd,
2546 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002547 hChildStderrWr,
2548 &hProcess))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002549 return win32_error("CreateProcess", NULL);
2550 }
2551
Mark Hammondb37a3732000-08-14 04:47:33 +00002552 /*
2553 * Insert the files we've created into the process dictionary
2554 * all referencing the list with the process handle and the
2555 * initial number of files (see description below in _PyPclose).
2556 * Since if _PyPclose later tried to wait on a process when all
2557 * handles weren't closed, it could create a deadlock with the
2558 * child, we spend some energy here to try to ensure that we
2559 * either insert all file handles into the dictionary or none
2560 * at all. It's a little clumsy with the various popen modes
2561 * and variable number of files involved.
2562 */
2563 if (!_PyPopenProcs) {
2564 _PyPopenProcs = PyDict_New();
2565 }
2566
2567 if (_PyPopenProcs) {
2568 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2569 int ins_rc[3];
2570
2571 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2572 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2573
2574 procObj = PyList_New(2);
2575 hProcessObj = PyLong_FromVoidPtr(hProcess);
2576 intObj = PyInt_FromLong(file_count);
2577
2578 if (procObj && hProcessObj && intObj) {
2579 PyList_SetItem(procObj,0,hProcessObj);
2580 PyList_SetItem(procObj,1,intObj);
2581
2582 fileObj[0] = PyLong_FromVoidPtr(f1);
2583 if (fileObj[0]) {
2584 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2585 fileObj[0],
2586 procObj);
2587 }
2588 if (file_count >= 2) {
2589 fileObj[1] = PyLong_FromVoidPtr(f2);
2590 if (fileObj[1]) {
2591 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2592 fileObj[1],
2593 procObj);
2594 }
2595 }
2596 if (file_count >= 3) {
2597 fileObj[2] = PyLong_FromVoidPtr(f3);
2598 if (fileObj[2]) {
2599 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2600 fileObj[2],
2601 procObj);
2602 }
2603 }
2604
2605 if (ins_rc[0] < 0 || !fileObj[0] ||
2606 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2607 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2608 /* Something failed - remove any dictionary
2609 * entries that did make it.
2610 */
2611 if (!ins_rc[0] && fileObj[0]) {
2612 PyDict_DelItem(_PyPopenProcs,
2613 fileObj[0]);
2614 }
2615 if (!ins_rc[1] && fileObj[1]) {
2616 PyDict_DelItem(_PyPopenProcs,
2617 fileObj[1]);
2618 }
2619 if (!ins_rc[2] && fileObj[2]) {
2620 PyDict_DelItem(_PyPopenProcs,
2621 fileObj[2]);
2622 }
2623 }
2624 }
2625
2626 /*
2627 * Clean up our localized references for the dictionary keys
2628 * and value since PyDict_SetItem will Py_INCREF any copies
2629 * that got placed in the dictionary.
2630 */
2631 Py_XDECREF(procObj);
2632 Py_XDECREF(fileObj[0]);
2633 Py_XDECREF(fileObj[1]);
2634 Py_XDECREF(fileObj[2]);
2635 }
2636
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002637 /* Child is launched. Close the parents copy of those pipe
2638 * handles that only the child should have open. You need to
2639 * make sure that no handles to the write end of the output pipe
2640 * are maintained in this process or else the pipe will not close
2641 * when the child process exits and the ReadFile will hang. */
2642
2643 if (!CloseHandle(hChildStdinRd))
2644 return win32_error("CloseHandle", NULL);
2645
2646 if (!CloseHandle(hChildStdoutWr))
2647 return win32_error("CloseHandle", NULL);
2648
2649 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2650 return win32_error("CloseHandle", NULL);
2651
2652 return f;
2653}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002654
2655/*
2656 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2657 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002658 *
2659 * This function uses the _PyPopenProcs dictionary in order to map the
2660 * input file pointer to information about the process that was
2661 * originally created by the popen* call that created the file pointer.
2662 * The dictionary uses the file pointer as a key (with one entry
2663 * inserted for each file returned by the original popen* call) and a
2664 * single list object as the value for all files from a single call.
2665 * The list object contains the Win32 process handle at [0], and a file
2666 * count at [1], which is initialized to the total number of file
2667 * handles using that list.
2668 *
2669 * This function closes whichever handle it is passed, and decrements
2670 * the file count in the dictionary for the process handle pointed to
2671 * by this file. On the last close (when the file count reaches zero),
2672 * this function will wait for the child process and then return its
2673 * exit code as the result of the close() operation. This permits the
2674 * files to be closed in any order - it is always the close() of the
2675 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002676 */
Tim Peters736aa322000-09-01 06:51:24 +00002677
2678 /* RED_FLAG 31-Aug-2000 Tim
2679 * This is always called (today!) between a pair of
2680 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2681 * macros. So the thread running this has no valid thread state, as
2682 * far as Python is concerned. However, this calls some Python API
2683 * functions that cannot be called safely without a valid thread
2684 * state, in particular PyDict_GetItem.
2685 * As a temporary hack (although it may last for years ...), we
2686 * *rely* on not having a valid thread state in this function, in
2687 * order to create our own "from scratch".
2688 * This will deadlock if _PyPclose is ever called by a thread
2689 * holding the global lock.
2690 */
2691
Fredrik Lundh56055a42000-07-23 19:47:12 +00002692static int _PyPclose(FILE *file)
2693{
Fredrik Lundh20318932000-07-26 17:29:12 +00002694 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002695 DWORD exit_code;
2696 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002697 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2698 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002699#ifdef WITH_THREAD
2700 PyInterpreterState* pInterpreterState;
2701 PyThreadState* pThreadState;
2702#endif
2703
Fredrik Lundh20318932000-07-26 17:29:12 +00002704 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002705 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002706 */
2707 result = fclose(file);
2708
Tim Peters736aa322000-09-01 06:51:24 +00002709#ifdef WITH_THREAD
2710 /* Bootstrap a valid thread state into existence. */
2711 pInterpreterState = PyInterpreterState_New();
2712 if (!pInterpreterState) {
2713 /* Well, we're hosed now! We don't have a thread
2714 * state, so can't call a nice error routine, or raise
2715 * an exception. Just die.
2716 */
2717 Py_FatalError("unable to allocate interpreter state "
Tim Peters9acdd3a2000-09-01 19:26:36 +00002718 "when closing popen object.");
Tim Peters736aa322000-09-01 06:51:24 +00002719 return -1; /* unreachable */
2720 }
2721 pThreadState = PyThreadState_New(pInterpreterState);
2722 if (!pThreadState) {
2723 Py_FatalError("unable to allocate thread state "
Tim Peters9acdd3a2000-09-01 19:26:36 +00002724 "when closing popen object.");
Tim Peters736aa322000-09-01 06:51:24 +00002725 return -1; /* unreachable */
2726 }
2727 /* Grab the global lock. Note that this will deadlock if the
2728 * current thread already has the lock! (see RED_FLAG comments
2729 * before this function)
2730 */
2731 PyEval_RestoreThread(pThreadState);
2732#endif
2733
Fredrik Lundh56055a42000-07-23 19:47:12 +00002734 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002735 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2736 (procObj = PyDict_GetItem(_PyPopenProcs,
2737 fileObj)) != NULL &&
2738 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2739 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2740
2741 hProcess = PyLong_AsVoidPtr(hProcessObj);
2742 file_count = PyInt_AsLong(intObj);
2743
2744 if (file_count > 1) {
2745 /* Still other files referencing process */
2746 file_count--;
2747 PyList_SetItem(procObj,1,
2748 PyInt_FromLong(file_count));
2749 } else {
2750 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002751 if (result != EOF &&
2752 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2753 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002754 /* Possible truncation here in 16-bit environments, but
2755 * real exit codes are just the lower byte in any event.
2756 */
2757 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002758 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002759 /* Indicate failure - this will cause the file object
2760 * to raise an I/O error and translate the last Win32
2761 * error code from errno. We do have a problem with
2762 * last errors that overlap the normal errno table,
2763 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002764 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002765 if (result != EOF) {
2766 /* If the error wasn't from the fclose(), then
2767 * set errno for the file object error handling.
2768 */
2769 errno = GetLastError();
2770 }
2771 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002772 }
2773
2774 /* Free up the native handle at this point */
2775 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002776 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002777
Mark Hammondb37a3732000-08-14 04:47:33 +00002778 /* Remove this file pointer from dictionary */
2779 PyDict_DelItem(_PyPopenProcs, fileObj);
2780
2781 if (PyDict_Size(_PyPopenProcs) == 0) {
2782 Py_DECREF(_PyPopenProcs);
2783 _PyPopenProcs = NULL;
2784 }
2785
2786 } /* if object retrieval ok */
2787
2788 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002789 } /* if _PyPopenProcs */
2790
Tim Peters736aa322000-09-01 06:51:24 +00002791#ifdef WITH_THREAD
2792 /* Tear down the thread & interpreter states.
2793 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002794 * call the thread clear & delete functions, and indeed insist on
2795 * doing that themselves. The lock must be held during the clear, but
2796 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002797 */
2798 PyInterpreterState_Clear(pInterpreterState);
2799 PyEval_ReleaseThread(pThreadState);
2800 PyInterpreterState_Delete(pInterpreterState);
2801#endif
2802
Fredrik Lundh56055a42000-07-23 19:47:12 +00002803 return result;
2804}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002805
2806#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002807static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002808posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00002809{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002810 char *name;
2811 char *mode = "r";
2812 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00002813 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00002814 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002815 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00002816 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002817 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002818 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00002819 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00002820 if (fp == NULL)
2821 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002822 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002823 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00002824 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00002825 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00002826}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002827#endif
2828
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002829#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00002830
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002831
Guido van Rossumb6775db1994-08-01 11:34:53 +00002832#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002833static char posix_setuid__doc__[] =
2834"setuid(uid) -> None\n\
2835Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00002836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002837posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002838{
2839 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002840 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002841 return NULL;
2842 if (setuid(uid) < 0)
2843 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002844 Py_INCREF(Py_None);
2845 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002846}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002847#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002849
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00002850#ifdef HAVE_SETEUID
2851static char posix_seteuid__doc__[] =
2852"seteuid(uid) -> None\n\
2853Set the current process's effective user id.";
2854static PyObject *
2855posix_seteuid (PyObject *self, PyObject *args)
2856{
2857 int euid;
2858 if (!PyArg_ParseTuple(args, "i", &euid)) {
2859 return NULL;
2860 } else if (seteuid(euid) < 0) {
2861 return posix_error();
2862 } else {
2863 Py_INCREF(Py_None);
2864 return Py_None;
2865 }
2866}
2867#endif /* HAVE_SETEUID */
2868
2869#ifdef HAVE_SETEGID
2870static char posix_setegid__doc__[] =
2871"setegid(gid) -> None\n\
2872Set the current process's effective group id.";
2873static PyObject *
2874posix_setegid (PyObject *self, PyObject *args)
2875{
2876 int egid;
2877 if (!PyArg_ParseTuple(args, "i", &egid)) {
2878 return NULL;
2879 } else if (setegid(egid) < 0) {
2880 return posix_error();
2881 } else {
2882 Py_INCREF(Py_None);
2883 return Py_None;
2884 }
2885}
2886#endif /* HAVE_SETEGID */
2887
2888#ifdef HAVE_SETREUID
2889static char posix_setreuid__doc__[] =
2890"seteuid(ruid, euid) -> None\n\
2891Set the current process's real and effective user ids.";
2892static PyObject *
2893posix_setreuid (PyObject *self, PyObject *args)
2894{
2895 int ruid, euid;
2896 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2897 return NULL;
2898 } else if (setreuid(ruid, euid) < 0) {
2899 return posix_error();
2900 } else {
2901 Py_INCREF(Py_None);
2902 return Py_None;
2903 }
2904}
2905#endif /* HAVE_SETREUID */
2906
2907#ifdef HAVE_SETREGID
2908static char posix_setregid__doc__[] =
2909"setegid(rgid, egid) -> None\n\
2910Set the current process's real and effective group ids.";
2911static PyObject *
2912posix_setregid (PyObject *self, PyObject *args)
2913{
2914 int rgid, egid;
2915 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2916 return NULL;
2917 } else if (setregid(rgid, egid) < 0) {
2918 return posix_error();
2919 } else {
2920 Py_INCREF(Py_None);
2921 return Py_None;
2922 }
2923}
2924#endif /* HAVE_SETREGID */
2925
Guido van Rossumb6775db1994-08-01 11:34:53 +00002926#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002927static char posix_setgid__doc__[] =
2928"setgid(gid) -> None\n\
2929Set the current process's group id.";
2930
Barry Warsaw53699e91996-12-10 23:23:01 +00002931static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002932posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002933{
2934 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002935 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002936 return NULL;
2937 if (setgid(gid) < 0)
2938 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002939 Py_INCREF(Py_None);
2940 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002941}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002942#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00002943
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002944
Guido van Rossumb6775db1994-08-01 11:34:53 +00002945#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002946static char posix_waitpid__doc__[] =
2947"waitpid(pid, options) -> (pid, status)\n\
2948Wait for completion of a give child process.";
2949
Barry Warsaw53699e91996-12-10 23:23:01 +00002950static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002951posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002952{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002953 int pid, options;
2954#ifdef UNION_WAIT
2955 union wait status;
2956#define status_i (status.w_status)
2957#else
2958 int status;
2959#define status_i status
2960#endif
2961 status_i = 0;
2962
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002963 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00002964 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002965 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002966#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002967 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00002968#else
2969 pid = waitpid(pid, &status, options);
2970#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002971 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00002972 if (pid == -1)
2973 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00002974 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002975 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00002976}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002977#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00002978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002979
Guido van Rossumad0ee831995-03-01 10:34:45 +00002980#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002981static char posix_wait__doc__[] =
2982"wait() -> (pid, status)\n\
2983Wait for completion of a child process.";
2984
Barry Warsaw53699e91996-12-10 23:23:01 +00002985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002986posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00002987{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002988 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002989#ifdef UNION_WAIT
2990 union wait status;
2991#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002992#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002993 int status;
2994#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00002995#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002996 if (!PyArg_ParseTuple(args, ":wait"))
2997 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00002998 status_i = 0;
2999 Py_BEGIN_ALLOW_THREADS
3000 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003001 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003002 if (pid == -1)
3003 return posix_error();
3004 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003005 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003006#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003007}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003008#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003010
3011static char posix_lstat__doc__[] =
3012"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3013Like stat(path), but do not follow symbolic links.";
3014
Barry Warsaw53699e91996-12-10 23:23:01 +00003015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003016posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003017{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003018#ifdef HAVE_LSTAT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003019 return posix_do_stat(self, args, "s:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003020#else /* !HAVE_LSTAT */
Fred Drake699f3522000-06-29 21:12:41 +00003021 return posix_do_stat(self, args, "s:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003022#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003023}
3024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003025
Guido van Rossumb6775db1994-08-01 11:34:53 +00003026#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003027static char posix_readlink__doc__[] =
3028"readlink(path) -> path\n\
3029Return a string representing the path to which the symbolic link points.";
3030
Barry Warsaw53699e91996-12-10 23:23:01 +00003031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003032posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003033{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003034 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003035 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003036 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003037 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003038 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003039 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003040 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003041 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003042 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003043 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003044 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003045}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003046#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003048
Guido van Rossumb6775db1994-08-01 11:34:53 +00003049#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003050static char posix_symlink__doc__[] =
3051"symlink(src, dst) -> None\n\
3052Create a symbolic link.";
3053
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003054static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003055posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003056{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003057 return posix_2str(args, "ss:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003058}
3059#endif /* HAVE_SYMLINK */
3060
3061
3062#ifdef HAVE_TIMES
3063#ifndef HZ
3064#define HZ 60 /* Universal constant :-) */
3065#endif /* HZ */
3066
Guido van Rossumd48f2521997-12-05 22:19:34 +00003067#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3068static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003069system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003070{
3071 ULONG value = 0;
3072
3073 Py_BEGIN_ALLOW_THREADS
3074 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3075 Py_END_ALLOW_THREADS
3076
3077 return value;
3078}
3079
3080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003081posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003082{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003083 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003084 return NULL;
3085
3086 /* Currently Only Uptime is Provided -- Others Later */
3087 return Py_BuildValue("ddddd",
3088 (double)0 /* t.tms_utime / HZ */,
3089 (double)0 /* t.tms_stime / HZ */,
3090 (double)0 /* t.tms_cutime / HZ */,
3091 (double)0 /* t.tms_cstime / HZ */,
3092 (double)system_uptime() / 1000);
3093}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003094#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003096posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003097{
3098 struct tms t;
3099 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003100 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003101 return NULL;
3102 errno = 0;
3103 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003104 if (c == (clock_t) -1)
3105 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003106 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003107 (double)t.tms_utime / HZ,
3108 (double)t.tms_stime / HZ,
3109 (double)t.tms_cutime / HZ,
3110 (double)t.tms_cstime / HZ,
3111 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003112}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003113#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003114#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003115
3116
Guido van Rossum87755a21996-09-07 00:59:43 +00003117#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003118#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003120posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003121{
3122 FILETIME create, exit, kernel, user;
3123 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003124 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003125 return NULL;
3126 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003127 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3128 /* The fields of a FILETIME structure are the hi and lo part
3129 of a 64-bit value expressed in 100 nanosecond units.
3130 1e7 is one second in such units; 1e-7 the inverse.
3131 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3132 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003133 return Py_BuildValue(
3134 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003135 (double)(kernel.dwHighDateTime*429.4967296 +
3136 kernel.dwLowDateTime*1e-7),
3137 (double)(user.dwHighDateTime*429.4967296 +
3138 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003139 (double)0,
3140 (double)0,
3141 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003142}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003143#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003144
3145#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003146static char posix_times__doc__[] =
3147"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3148Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003149#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003150
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003151
Guido van Rossumb6775db1994-08-01 11:34:53 +00003152#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003153static char posix_setsid__doc__[] =
3154"setsid() -> None\n\
3155Call the system call setsid().";
3156
Barry Warsaw53699e91996-12-10 23:23:01 +00003157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003158posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003159{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003160 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003161 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003162 if (setsid() < 0)
3163 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003164 Py_INCREF(Py_None);
3165 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003166}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003167#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003168
Guido van Rossumb6775db1994-08-01 11:34:53 +00003169#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003170static char posix_setpgid__doc__[] =
3171"setpgid(pid, pgrp) -> None\n\
3172Call the system call setpgid().";
3173
Barry Warsaw53699e91996-12-10 23:23:01 +00003174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003175posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003176{
3177 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003178 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003179 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003180 if (setpgid(pid, pgrp) < 0)
3181 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003182 Py_INCREF(Py_None);
3183 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003184}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003185#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003187
Guido van Rossumb6775db1994-08-01 11:34:53 +00003188#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003189static char posix_tcgetpgrp__doc__[] =
3190"tcgetpgrp(fd) -> pgid\n\
3191Return the process group associated with the terminal given by a fd.";
3192
Barry Warsaw53699e91996-12-10 23:23:01 +00003193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003194posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003195{
3196 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003197 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003198 return NULL;
3199 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003200 if (pgid < 0)
3201 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003202 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003203}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003204#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003205
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003206
Guido van Rossumb6775db1994-08-01 11:34:53 +00003207#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003208static char posix_tcsetpgrp__doc__[] =
3209"tcsetpgrp(fd, pgid) -> None\n\
3210Set the process group associated with the terminal given by a fd.";
3211
Barry Warsaw53699e91996-12-10 23:23:01 +00003212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003213posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003214{
3215 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003216 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003217 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003218 if (tcsetpgrp(fd, pgid) < 0)
3219 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003220 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003221 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003222}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003223#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003224
Guido van Rossum687dd131993-05-17 08:34:16 +00003225/* Functions acting on file descriptors */
3226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003227static char posix_open__doc__[] =
3228"open(filename, flag [, mode=0777]) -> fd\n\
3229Open a file (for low level IO).";
3230
Barry Warsaw53699e91996-12-10 23:23:01 +00003231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003232posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003233{
3234 char *file;
3235 int flag;
3236 int mode = 0777;
3237 int fd;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003238 if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3239 return NULL;
3240
Barry Warsaw53699e91996-12-10 23:23:01 +00003241 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003242 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003243 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003244 if (fd < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003245 return posix_error_with_filename(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003246 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003247}
3248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003249
3250static char posix_close__doc__[] =
3251"close(fd) -> None\n\
3252Close a file descriptor (for low level IO).";
3253
Barry Warsaw53699e91996-12-10 23:23:01 +00003254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003255posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003256{
3257 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003258 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003259 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003260 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003261 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003262 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003263 if (res < 0)
3264 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003265 Py_INCREF(Py_None);
3266 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003267}
3268
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003269
3270static char posix_dup__doc__[] =
3271"dup(fd) -> fd2\n\
3272Return a duplicate of a file descriptor.";
3273
Barry Warsaw53699e91996-12-10 23:23:01 +00003274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003275posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003276{
3277 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003278 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003279 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003280 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003281 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003282 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003283 if (fd < 0)
3284 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003285 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003286}
3287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003288
3289static char posix_dup2__doc__[] =
3290"dup2(fd, fd2) -> None\n\
3291Duplicate file descriptor.";
3292
Barry Warsaw53699e91996-12-10 23:23:01 +00003293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003294posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003295{
3296 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003297 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003298 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003299 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003300 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003301 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003302 if (res < 0)
3303 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003304 Py_INCREF(Py_None);
3305 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003306}
3307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003308
3309static char posix_lseek__doc__[] =
3310"lseek(fd, pos, how) -> newpos\n\
3311Set the current position of a file descriptor.";
3312
Barry Warsaw53699e91996-12-10 23:23:01 +00003313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003314posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003315{
3316 int fd, how;
Fred Drake699f3522000-06-29 21:12:41 +00003317#ifdef MS_WIN64
3318 LONG_LONG pos, res;
3319#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003320 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003321#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003322 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003323 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003324 return NULL;
3325#ifdef SEEK_SET
3326 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3327 switch (how) {
3328 case 0: how = SEEK_SET; break;
3329 case 1: how = SEEK_CUR; break;
3330 case 2: how = SEEK_END; break;
3331 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003332#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003333
3334#if !defined(HAVE_LARGEFILE_SUPPORT)
3335 pos = PyInt_AsLong(posobj);
3336#else
3337 pos = PyLong_Check(posobj) ?
3338 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3339#endif
3340 if (PyErr_Occurred())
3341 return NULL;
3342
Barry Warsaw53699e91996-12-10 23:23:01 +00003343 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003344#ifdef MS_WIN64
3345 res = _lseeki64(fd, pos, how);
3346#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003347 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003348#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003349 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003350 if (res < 0)
3351 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003352
3353#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003354 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003355#else
3356 return PyLong_FromLongLong(res);
3357#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003358}
3359
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003360
3361static char posix_read__doc__[] =
3362"read(fd, buffersize) -> string\n\
3363Read a file descriptor.";
3364
Barry Warsaw53699e91996-12-10 23:23:01 +00003365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003366posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003367{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003368 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003369 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003370 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003371 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003372 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003373 if (buffer == NULL)
3374 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003375 Py_BEGIN_ALLOW_THREADS
3376 n = read(fd, PyString_AsString(buffer), size);
3377 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003378 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003379 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003380 return posix_error();
3381 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003382 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003383 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003384 return buffer;
3385}
3386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003387
3388static char posix_write__doc__[] =
3389"write(fd, string) -> byteswritten\n\
3390Write a string to a file descriptor.";
3391
Barry Warsaw53699e91996-12-10 23:23:01 +00003392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003393posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003394{
3395 int fd, size;
3396 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003397 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003398 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003399 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003400 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003401 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003402 if (size < 0)
3403 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003404 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003405}
3406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003407
3408static char posix_fstat__doc__[]=
3409"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3410Like stat(), but for an open file descriptor.";
3411
Barry Warsaw53699e91996-12-10 23:23:01 +00003412static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003413posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003414{
3415 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003416 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003417 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003418 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003419 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003420 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003421 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003422 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003423 if (res != 0)
3424 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003425
3426 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003427}
3428
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003429
3430static char posix_fdopen__doc__[] =
3431"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3432Return an open file object connected to a file descriptor.";
3433
Barry Warsaw53699e91996-12-10 23:23:01 +00003434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003435posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003436{
Guido van Rossum687dd131993-05-17 08:34:16 +00003437 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003438 char *mode = "r";
3439 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003440 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003441 PyObject *f;
3442 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003443 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003444
Barry Warsaw53699e91996-12-10 23:23:01 +00003445 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003446 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003447 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003448 if (fp == NULL)
3449 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003450 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003451 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003452 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003453 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003454}
3455
Skip Montanaro1517d842000-07-19 14:34:14 +00003456static char posix_isatty__doc__[] =
3457"isatty(fd) -> Boolean\n\
3458Return true if the file descriptor 'fd' is an open file descriptor\n\
3459connected to a terminal.";
3460
3461static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003462posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003463{
3464 int fd;
3465 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3466 return NULL;
3467 return Py_BuildValue("i", isatty(fd));
3468}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003469
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003470#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003471static char posix_pipe__doc__[] =
3472"pipe() -> (read_end, write_end)\n\
3473Create a pipe.";
3474
Barry Warsaw53699e91996-12-10 23:23:01 +00003475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003476posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003477{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003478#if defined(PYOS_OS2)
3479 HFILE read, write;
3480 APIRET rc;
3481
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003482 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003483 return NULL;
3484
3485 Py_BEGIN_ALLOW_THREADS
3486 rc = DosCreatePipe( &read, &write, 4096);
3487 Py_END_ALLOW_THREADS
3488 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003489 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003490
3491 return Py_BuildValue("(ii)", read, write);
3492#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003493#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003494 int fds[2];
3495 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003496 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003497 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003498 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003499 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003500 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003501 if (res != 0)
3502 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003503 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003504#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003505 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003506 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003507 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003508 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003509 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003510 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003511 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003512 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003513 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003514 return win32_error("CreatePipe", NULL);
Fred Drake699f3522000-06-29 21:12:41 +00003515 read_fd = _open_osfhandle((intptr_t)read, 0);
3516 write_fd = _open_osfhandle((intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003517 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003518#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003519#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003520}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003521#endif /* HAVE_PIPE */
3522
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003523
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003524#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003525static char posix_mkfifo__doc__[] =
3526"mkfifo(file, [, mode=0666]) -> None\n\
3527Create a FIFO (a POSIX named pipe).";
3528
Barry Warsaw53699e91996-12-10 23:23:01 +00003529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003530posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003531{
3532 char *file;
3533 int mode = 0666;
3534 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003535 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003536 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003537 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003538 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003539 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003540 if (res < 0)
3541 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003542 Py_INCREF(Py_None);
3543 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003544}
3545#endif
3546
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003547
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003548#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003549static char posix_ftruncate__doc__[] =
3550"ftruncate(fd, length) -> None\n\
3551Truncate a file to a specified length.";
3552
Barry Warsaw53699e91996-12-10 23:23:01 +00003553static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003554posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003555{
3556 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003557 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003558 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003559 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003560
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003561 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003562 return NULL;
3563
3564#if !defined(HAVE_LARGEFILE_SUPPORT)
3565 length = PyInt_AsLong(lenobj);
3566#else
3567 length = PyLong_Check(lenobj) ?
3568 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3569#endif
3570 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003571 return NULL;
3572
Barry Warsaw53699e91996-12-10 23:23:01 +00003573 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003574 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003575 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003576 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003577 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003578 return NULL;
3579 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003580 Py_INCREF(Py_None);
3581 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003582}
3583#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003584
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003585#ifdef NeXT
3586#define HAVE_PUTENV
3587/* Steve Spicklemire got this putenv from NeXTAnswers */
3588static int
3589putenv(char *newval)
3590{
3591 extern char **environ;
3592
3593 static int firstTime = 1;
3594 char **ep;
3595 char *cp;
3596 int esiz;
3597 char *np;
3598
3599 if (!(np = strchr(newval, '=')))
3600 return 1;
3601 *np = '\0';
3602
3603 /* look it up */
3604 for (ep=environ ; *ep ; ep++)
3605 {
3606 /* this should always be true... */
3607 if (cp = strchr(*ep, '='))
3608 {
3609 *cp = '\0';
3610 if (!strcmp(*ep, newval))
3611 {
3612 /* got it! */
3613 *cp = '=';
3614 break;
3615 }
3616 *cp = '=';
3617 }
3618 else
3619 {
3620 *np = '=';
3621 return 1;
3622 }
3623 }
3624
3625 *np = '=';
3626 if (*ep)
3627 {
3628 /* the string was already there:
3629 just replace it with the new one */
3630 *ep = newval;
3631 return 0;
3632 }
3633
3634 /* expand environ by one */
3635 for (esiz=2, ep=environ ; *ep ; ep++)
3636 esiz++;
3637 if (firstTime)
3638 {
3639 char **epp;
3640 char **newenv;
3641 if (!(newenv = malloc(esiz * sizeof(char *))))
3642 return 1;
3643
3644 for (ep=environ, epp=newenv ; *ep ;)
3645 *epp++ = *ep++;
3646 *epp++ = newval;
3647 *epp = (char *) 0;
3648 environ = newenv;
3649 }
3650 else
3651 {
3652 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3653 return 1;
3654 environ[esiz - 2] = newval;
3655 environ[esiz - 1] = (char *) 0;
3656 firstTime = 0;
3657 }
3658
3659 return 0;
3660}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003661#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003662
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003663
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003664#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003665static char posix_putenv__doc__[] =
3666"putenv(key, value) -> None\n\
3667Change or add an environment variable.";
3668
Fred Drake762e2061999-08-26 17:23:54 +00003669/* Save putenv() parameters as values here, so we can collect them when they
3670 * get re-set with another call for the same key. */
3671static PyObject *posix_putenv_garbage;
3672
Barry Warsaw53699e91996-12-10 23:23:01 +00003673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003674posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003675{
3676 char *s1, *s2;
3677 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003678 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003679
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003680 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003681 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003682
3683#if defined(PYOS_OS2)
3684 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3685 APIRET rc;
3686
3687 if (strlen(s2) == 0) /* If New Value is an Empty String */
3688 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3689
3690 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3691 if (rc != NO_ERROR)
3692 return os2_error(rc);
3693
3694 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3695 APIRET rc;
3696
3697 if (strlen(s2) == 0) /* If New Value is an Empty String */
3698 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3699
3700 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3701 if (rc != NO_ERROR)
3702 return os2_error(rc);
3703 } else {
3704#endif
3705
Fred Drake762e2061999-08-26 17:23:54 +00003706 /* XXX This can leak memory -- not easy to fix :-( */
3707 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3708 if (newstr == NULL)
3709 return PyErr_NoMemory();
3710 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003711 (void) sprintf(new, "%s=%s", s1, s2);
3712 if (putenv(new)) {
3713 posix_error();
3714 return NULL;
3715 }
Fred Drake762e2061999-08-26 17:23:54 +00003716 /* Install the first arg and newstr in posix_putenv_garbage;
3717 * this will cause previous value to be collected. This has to
3718 * happen after the real putenv() call because the old value
3719 * was still accessible until then. */
3720 if (PyDict_SetItem(posix_putenv_garbage,
3721 PyTuple_GET_ITEM(args, 0), newstr)) {
3722 /* really not much we can do; just leak */
3723 PyErr_Clear();
3724 }
3725 else {
3726 Py_DECREF(newstr);
3727 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003728
3729#if defined(PYOS_OS2)
3730 }
3731#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003732 Py_INCREF(Py_None);
3733 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003734}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003735#endif /* putenv */
3736
3737#ifdef HAVE_STRERROR
3738static char posix_strerror__doc__[] =
3739"strerror(code) -> string\n\
3740Translate an error code to a message string.";
3741
3742PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003743posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003744{
3745 int code;
3746 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003747 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003748 return NULL;
3749 message = strerror(code);
3750 if (message == NULL) {
3751 PyErr_SetString(PyExc_ValueError,
3752 "strerror code out of range");
3753 return NULL;
3754 }
3755 return PyString_FromString(message);
3756}
3757#endif /* strerror */
3758
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003759
Guido van Rossumc9641791998-08-04 15:26:23 +00003760#ifdef HAVE_SYS_WAIT_H
3761
3762#ifdef WIFSTOPPED
3763static char posix_WIFSTOPPED__doc__[] =
3764"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003765Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003766
3767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003768posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003769{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003770#ifdef UNION_WAIT
3771 union wait status;
3772#define status_i (status.w_status)
3773#else
3774 int status;
3775#define status_i status
3776#endif
3777 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003778
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003779 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003780 {
3781 return NULL;
3782 }
3783
3784 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003785#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003786}
3787#endif /* WIFSTOPPED */
3788
3789#ifdef WIFSIGNALED
3790static char posix_WIFSIGNALED__doc__[] =
3791"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00003792Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003793
3794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003795posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003796{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003797#ifdef UNION_WAIT
3798 union wait status;
3799#define status_i (status.w_status)
3800#else
3801 int status;
3802#define status_i status
3803#endif
3804 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003805
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003806 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003807 {
3808 return NULL;
3809 }
3810
3811 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003812#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003813}
3814#endif /* WIFSIGNALED */
3815
3816#ifdef WIFEXITED
3817static char posix_WIFEXITED__doc__[] =
3818"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003819Return true if the process returning 'status' exited using the exit()\n\
3820system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003821
3822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003823posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003824{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003825#ifdef UNION_WAIT
3826 union wait status;
3827#define status_i (status.w_status)
3828#else
3829 int status;
3830#define status_i status
3831#endif
3832 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003833
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003834 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003835 {
3836 return NULL;
3837 }
3838
3839 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003840#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003841}
3842#endif /* WIFEXITED */
3843
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003844#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00003845static char posix_WEXITSTATUS__doc__[] =
3846"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003847Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003848
3849static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003850posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003851{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003852#ifdef UNION_WAIT
3853 union wait status;
3854#define status_i (status.w_status)
3855#else
3856 int status;
3857#define status_i status
3858#endif
3859 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003860
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003861 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003862 {
3863 return NULL;
3864 }
3865
3866 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003867#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003868}
3869#endif /* WEXITSTATUS */
3870
3871#ifdef WTERMSIG
3872static char posix_WTERMSIG__doc__[] =
3873"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003874Return the signal that terminated the process that provided the 'status'\n\
3875value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003876
3877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003878posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003879{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003880#ifdef UNION_WAIT
3881 union wait status;
3882#define status_i (status.w_status)
3883#else
3884 int status;
3885#define status_i status
3886#endif
3887 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003888
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003889 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003890 {
3891 return NULL;
3892 }
3893
3894 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003895#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003896}
3897#endif /* WTERMSIG */
3898
3899#ifdef WSTOPSIG
3900static char posix_WSTOPSIG__doc__[] =
3901"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00003902Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00003903
3904static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003905posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00003906{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003907#ifdef UNION_WAIT
3908 union wait status;
3909#define status_i (status.w_status)
3910#else
3911 int status;
3912#define status_i status
3913#endif
3914 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00003915
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003916 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00003917 {
3918 return NULL;
3919 }
3920
3921 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003922#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00003923}
3924#endif /* WSTOPSIG */
3925
3926#endif /* HAVE_SYS_WAIT_H */
3927
3928
Guido van Rossum94f6f721999-01-06 18:42:14 +00003929#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00003930#ifdef _SCO_DS
3931/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3932 needed definitions in sys/statvfs.h */
3933#define _SVID3
3934#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003935#include <sys/statvfs.h>
3936
3937static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003938"fstatvfs(fd) -> \n\
3939 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003940Perform an fstatvfs system call on the given fd.";
3941
3942static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003943posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003944{
3945 int fd, res;
3946 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003947 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003948 return NULL;
3949 Py_BEGIN_ALLOW_THREADS
3950 res = fstatvfs(fd, &st);
3951 Py_END_ALLOW_THREADS
3952 if (res != 0)
3953 return posix_error();
3954#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003955 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003956 (long) st.f_bsize,
3957 (long) st.f_frsize,
3958 (long) st.f_blocks,
3959 (long) st.f_bfree,
3960 (long) st.f_bavail,
3961 (long) st.f_files,
3962 (long) st.f_ffree,
3963 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003964 (long) st.f_flag,
3965 (long) st.f_namemax);
3966#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003967 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00003968 (long) st.f_bsize,
3969 (long) st.f_frsize,
3970 (LONG_LONG) st.f_blocks,
3971 (LONG_LONG) st.f_bfree,
3972 (LONG_LONG) st.f_bavail,
3973 (LONG_LONG) st.f_files,
3974 (LONG_LONG) st.f_ffree,
3975 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00003976 (long) st.f_flag,
3977 (long) st.f_namemax);
3978#endif
3979}
3980#endif /* HAVE_FSTATVFS */
3981
3982
3983#if defined(HAVE_STATVFS)
3984#include <sys/statvfs.h>
3985
3986static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00003987"statvfs(path) -> \n\
3988 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00003989Perform a statvfs system call on the given path.";
3990
3991static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003992posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00003993{
3994 char *path;
3995 int res;
3996 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003997 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003998 return NULL;
3999 Py_BEGIN_ALLOW_THREADS
4000 res = statvfs(path, &st);
4001 Py_END_ALLOW_THREADS
4002 if (res != 0)
4003 return posix_error_with_filename(path);
4004#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004005 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004006 (long) st.f_bsize,
4007 (long) st.f_frsize,
4008 (long) st.f_blocks,
4009 (long) st.f_bfree,
4010 (long) st.f_bavail,
4011 (long) st.f_files,
4012 (long) st.f_ffree,
4013 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004014 (long) st.f_flag,
4015 (long) st.f_namemax);
4016#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004017 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004018 (long) st.f_bsize,
4019 (long) st.f_frsize,
4020 (LONG_LONG) st.f_blocks,
4021 (LONG_LONG) st.f_bfree,
4022 (LONG_LONG) st.f_bavail,
4023 (LONG_LONG) st.f_files,
4024 (LONG_LONG) st.f_ffree,
4025 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004026 (long) st.f_flag,
4027 (long) st.f_namemax);
4028#endif
4029}
4030#endif /* HAVE_STATVFS */
4031
4032
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004033#ifdef HAVE_TEMPNAM
4034static char posix_tempnam__doc__[] = "\
4035tempnam([dir[, prefix]]) -> string\n\
4036Return a unique name for a temporary file.\n\
4037The directory and a short may be specified as strings; they may be omitted\n\
4038or None if not needed.";
4039
4040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004041posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004042{
4043 PyObject *result = NULL;
4044 char *dir = NULL;
4045 char *pfx = NULL;
4046 char *name;
4047
4048 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4049 return NULL;
4050 name = tempnam(dir, pfx);
4051 if (name == NULL)
4052 return PyErr_NoMemory();
4053 result = PyString_FromString(name);
4054 free(name);
4055 return result;
4056}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004057#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004058
4059
4060#ifdef HAVE_TMPFILE
4061static char posix_tmpfile__doc__[] = "\
4062tmpfile() -> file object\n\
4063Create a temporary file with no directory entries.";
4064
4065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004066posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004067{
4068 FILE *fp;
4069
4070 if (!PyArg_ParseTuple(args, ":tmpfile"))
4071 return NULL;
4072 fp = tmpfile();
4073 if (fp == NULL)
4074 return posix_error();
4075 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4076}
4077#endif
4078
4079
4080#ifdef HAVE_TMPNAM
4081static char posix_tmpnam__doc__[] = "\
4082tmpnam() -> string\n\
4083Return a unique name for a temporary file.";
4084
4085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004086posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004087{
4088 char buffer[L_tmpnam];
4089 char *name;
4090
4091 if (!PyArg_ParseTuple(args, ":tmpnam"))
4092 return NULL;
Greg Wardb48bc172000-03-01 21:51:56 +00004093#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004094 name = tmpnam_r(buffer);
4095#else
4096 name = tmpnam(buffer);
4097#endif
4098 if (name == NULL) {
4099 PyErr_SetObject(PyExc_OSError,
4100 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004101#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004102 "unexpected NULL from tmpnam_r"
4103#else
4104 "unexpected NULL from tmpnam"
4105#endif
4106 ));
4107 return NULL;
4108 }
4109 return PyString_FromString(buffer);
4110}
4111#endif
4112
4113
Fred Drakec9680921999-12-13 16:37:25 +00004114/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4115 * It maps strings representing configuration variable names to
4116 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004117 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004118 * rarely-used constants. There are three separate tables that use
4119 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004120 *
4121 * This code is always included, even if none of the interfaces that
4122 * need it are included. The #if hackery needed to avoid it would be
4123 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004124 */
4125struct constdef {
4126 char *name;
4127 long value;
4128};
4129
Fred Drake12c6e2d1999-12-14 21:25:03 +00004130static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004131conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4132 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004133{
4134 if (PyInt_Check(arg)) {
4135 *valuep = PyInt_AS_LONG(arg);
4136 return 1;
4137 }
4138 if (PyString_Check(arg)) {
4139 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004140 size_t lo = 0;
4141 size_t mid;
4142 size_t hi = tablesize;
4143 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004144 char *confname = PyString_AS_STRING(arg);
4145 while (lo < hi) {
4146 mid = (lo + hi) / 2;
4147 cmp = strcmp(confname, table[mid].name);
4148 if (cmp < 0)
4149 hi = mid;
4150 else if (cmp > 0)
4151 lo = mid + 1;
4152 else {
4153 *valuep = table[mid].value;
4154 return 1;
4155 }
4156 }
4157 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4158 }
4159 else
4160 PyErr_SetString(PyExc_TypeError,
4161 "configuration names must be strings or integers");
4162 return 0;
4163}
4164
4165
4166#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4167static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004168#ifdef _PC_ABI_AIO_XFER_MAX
4169 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4170#endif
4171#ifdef _PC_ABI_ASYNC_IO
4172 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4173#endif
Fred Drakec9680921999-12-13 16:37:25 +00004174#ifdef _PC_ASYNC_IO
4175 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4176#endif
4177#ifdef _PC_CHOWN_RESTRICTED
4178 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4179#endif
4180#ifdef _PC_FILESIZEBITS
4181 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4182#endif
4183#ifdef _PC_LAST
4184 {"PC_LAST", _PC_LAST},
4185#endif
4186#ifdef _PC_LINK_MAX
4187 {"PC_LINK_MAX", _PC_LINK_MAX},
4188#endif
4189#ifdef _PC_MAX_CANON
4190 {"PC_MAX_CANON", _PC_MAX_CANON},
4191#endif
4192#ifdef _PC_MAX_INPUT
4193 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4194#endif
4195#ifdef _PC_NAME_MAX
4196 {"PC_NAME_MAX", _PC_NAME_MAX},
4197#endif
4198#ifdef _PC_NO_TRUNC
4199 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4200#endif
4201#ifdef _PC_PATH_MAX
4202 {"PC_PATH_MAX", _PC_PATH_MAX},
4203#endif
4204#ifdef _PC_PIPE_BUF
4205 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4206#endif
4207#ifdef _PC_PRIO_IO
4208 {"PC_PRIO_IO", _PC_PRIO_IO},
4209#endif
4210#ifdef _PC_SOCK_MAXBUF
4211 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4212#endif
4213#ifdef _PC_SYNC_IO
4214 {"PC_SYNC_IO", _PC_SYNC_IO},
4215#endif
4216#ifdef _PC_VDISABLE
4217 {"PC_VDISABLE", _PC_VDISABLE},
4218#endif
4219};
4220
Fred Drakec9680921999-12-13 16:37:25 +00004221static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004222conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004223{
4224 return conv_confname(arg, valuep, posix_constants_pathconf,
4225 sizeof(posix_constants_pathconf)
4226 / sizeof(struct constdef));
4227}
4228#endif
4229
4230#ifdef HAVE_FPATHCONF
4231static char posix_fpathconf__doc__[] = "\
4232fpathconf(fd, name) -> integer\n\
4233Return the configuration limit name for the file descriptor fd.\n\
4234If there is no limit, return -1.";
4235
4236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004237posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004238{
4239 PyObject *result = NULL;
4240 int name, fd;
4241
Fred Drake12c6e2d1999-12-14 21:25:03 +00004242 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4243 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004244 long limit;
4245
4246 errno = 0;
4247 limit = fpathconf(fd, name);
4248 if (limit == -1 && errno != 0)
4249 posix_error();
4250 else
4251 result = PyInt_FromLong(limit);
4252 }
4253 return result;
4254}
4255#endif
4256
4257
4258#ifdef HAVE_PATHCONF
4259static char posix_pathconf__doc__[] = "\
4260pathconf(path, name) -> integer\n\
4261Return the configuration limit name for the file or directory path.\n\
4262If there is no limit, return -1.";
4263
4264static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004265posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004266{
4267 PyObject *result = NULL;
4268 int name;
4269 char *path;
4270
4271 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4272 conv_path_confname, &name)) {
4273 long limit;
4274
4275 errno = 0;
4276 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004277 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004278 if (errno == EINVAL)
4279 /* could be a path or name problem */
4280 posix_error();
4281 else
4282 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004283 }
Fred Drakec9680921999-12-13 16:37:25 +00004284 else
4285 result = PyInt_FromLong(limit);
4286 }
4287 return result;
4288}
4289#endif
4290
4291#ifdef HAVE_CONFSTR
4292static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004293#ifdef _CS_ARCHITECTURE
4294 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4295#endif
4296#ifdef _CS_HOSTNAME
4297 {"CS_HOSTNAME", _CS_HOSTNAME},
4298#endif
4299#ifdef _CS_HW_PROVIDER
4300 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4301#endif
4302#ifdef _CS_HW_SERIAL
4303 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4304#endif
4305#ifdef _CS_INITTAB_NAME
4306 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4307#endif
Fred Drakec9680921999-12-13 16:37:25 +00004308#ifdef _CS_LFS64_CFLAGS
4309 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4310#endif
4311#ifdef _CS_LFS64_LDFLAGS
4312 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4313#endif
4314#ifdef _CS_LFS64_LIBS
4315 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4316#endif
4317#ifdef _CS_LFS64_LINTFLAGS
4318 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4319#endif
4320#ifdef _CS_LFS_CFLAGS
4321 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4322#endif
4323#ifdef _CS_LFS_LDFLAGS
4324 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4325#endif
4326#ifdef _CS_LFS_LIBS
4327 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4328#endif
4329#ifdef _CS_LFS_LINTFLAGS
4330 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4331#endif
Fred Draked86ed291999-12-15 15:34:33 +00004332#ifdef _CS_MACHINE
4333 {"CS_MACHINE", _CS_MACHINE},
4334#endif
Fred Drakec9680921999-12-13 16:37:25 +00004335#ifdef _CS_PATH
4336 {"CS_PATH", _CS_PATH},
4337#endif
Fred Draked86ed291999-12-15 15:34:33 +00004338#ifdef _CS_RELEASE
4339 {"CS_RELEASE", _CS_RELEASE},
4340#endif
4341#ifdef _CS_SRPC_DOMAIN
4342 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4343#endif
4344#ifdef _CS_SYSNAME
4345 {"CS_SYSNAME", _CS_SYSNAME},
4346#endif
4347#ifdef _CS_VERSION
4348 {"CS_VERSION", _CS_VERSION},
4349#endif
Fred Drakec9680921999-12-13 16:37:25 +00004350#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4351 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4352#endif
4353#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4354 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4355#endif
4356#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4357 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4358#endif
4359#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4360 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4361#endif
4362#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4363 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4364#endif
4365#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4366 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4367#endif
4368#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4369 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4370#endif
4371#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4372 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4373#endif
4374#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4375 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4376#endif
4377#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4378 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4379#endif
4380#ifdef _CS_XBS5_LP64_OFF64_LIBS
4381 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4382#endif
4383#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4384 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4385#endif
4386#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4387 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4388#endif
4389#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4390 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4391#endif
4392#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4393 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4394#endif
4395#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4396 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4397#endif
Fred Draked86ed291999-12-15 15:34:33 +00004398#ifdef _MIPS_CS_AVAIL_PROCESSORS
4399 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4400#endif
4401#ifdef _MIPS_CS_BASE
4402 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4403#endif
4404#ifdef _MIPS_CS_HOSTID
4405 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4406#endif
4407#ifdef _MIPS_CS_HW_NAME
4408 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4409#endif
4410#ifdef _MIPS_CS_NUM_PROCESSORS
4411 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4412#endif
4413#ifdef _MIPS_CS_OSREL_MAJ
4414 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4415#endif
4416#ifdef _MIPS_CS_OSREL_MIN
4417 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4418#endif
4419#ifdef _MIPS_CS_OSREL_PATCH
4420 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4421#endif
4422#ifdef _MIPS_CS_OS_NAME
4423 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4424#endif
4425#ifdef _MIPS_CS_OS_PROVIDER
4426 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4427#endif
4428#ifdef _MIPS_CS_PROCESSORS
4429 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4430#endif
4431#ifdef _MIPS_CS_SERIAL
4432 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4433#endif
4434#ifdef _MIPS_CS_VENDOR
4435 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4436#endif
Fred Drakec9680921999-12-13 16:37:25 +00004437};
4438
4439static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004440conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004441{
4442 return conv_confname(arg, valuep, posix_constants_confstr,
4443 sizeof(posix_constants_confstr)
4444 / sizeof(struct constdef));
4445}
4446
4447static char posix_confstr__doc__[] = "\
4448confstr(name) -> string\n\
4449Return a string-valued system configuration variable.";
4450
4451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004452posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004453{
4454 PyObject *result = NULL;
4455 int name;
4456 char buffer[64];
4457
4458 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4459 int len = confstr(name, buffer, sizeof(buffer));
4460
Fred Drakec9680921999-12-13 16:37:25 +00004461 errno = 0;
4462 if (len == 0) {
4463 if (errno != 0)
4464 posix_error();
4465 else
4466 result = PyString_FromString("");
4467 }
4468 else {
4469 if (len >= sizeof(buffer)) {
4470 result = PyString_FromStringAndSize(NULL, len);
4471 if (result != NULL)
4472 confstr(name, PyString_AS_STRING(result), len+1);
4473 }
4474 else
4475 result = PyString_FromString(buffer);
4476 }
4477 }
4478 return result;
4479}
4480#endif
4481
4482
4483#ifdef HAVE_SYSCONF
4484static struct constdef posix_constants_sysconf[] = {
4485#ifdef _SC_2_CHAR_TERM
4486 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4487#endif
4488#ifdef _SC_2_C_BIND
4489 {"SC_2_C_BIND", _SC_2_C_BIND},
4490#endif
4491#ifdef _SC_2_C_DEV
4492 {"SC_2_C_DEV", _SC_2_C_DEV},
4493#endif
4494#ifdef _SC_2_C_VERSION
4495 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4496#endif
4497#ifdef _SC_2_FORT_DEV
4498 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4499#endif
4500#ifdef _SC_2_FORT_RUN
4501 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4502#endif
4503#ifdef _SC_2_LOCALEDEF
4504 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4505#endif
4506#ifdef _SC_2_SW_DEV
4507 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4508#endif
4509#ifdef _SC_2_UPE
4510 {"SC_2_UPE", _SC_2_UPE},
4511#endif
4512#ifdef _SC_2_VERSION
4513 {"SC_2_VERSION", _SC_2_VERSION},
4514#endif
Fred Draked86ed291999-12-15 15:34:33 +00004515#ifdef _SC_ABI_ASYNCHRONOUS_IO
4516 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4517#endif
4518#ifdef _SC_ACL
4519 {"SC_ACL", _SC_ACL},
4520#endif
Fred Drakec9680921999-12-13 16:37:25 +00004521#ifdef _SC_AIO_LISTIO_MAX
4522 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4523#endif
Fred Drakec9680921999-12-13 16:37:25 +00004524#ifdef _SC_AIO_MAX
4525 {"SC_AIO_MAX", _SC_AIO_MAX},
4526#endif
4527#ifdef _SC_AIO_PRIO_DELTA_MAX
4528 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4529#endif
4530#ifdef _SC_ARG_MAX
4531 {"SC_ARG_MAX", _SC_ARG_MAX},
4532#endif
4533#ifdef _SC_ASYNCHRONOUS_IO
4534 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4535#endif
4536#ifdef _SC_ATEXIT_MAX
4537 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4538#endif
Fred Draked86ed291999-12-15 15:34:33 +00004539#ifdef _SC_AUDIT
4540 {"SC_AUDIT", _SC_AUDIT},
4541#endif
Fred Drakec9680921999-12-13 16:37:25 +00004542#ifdef _SC_AVPHYS_PAGES
4543 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4544#endif
4545#ifdef _SC_BC_BASE_MAX
4546 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4547#endif
4548#ifdef _SC_BC_DIM_MAX
4549 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4550#endif
4551#ifdef _SC_BC_SCALE_MAX
4552 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4553#endif
4554#ifdef _SC_BC_STRING_MAX
4555 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4556#endif
Fred Draked86ed291999-12-15 15:34:33 +00004557#ifdef _SC_CAP
4558 {"SC_CAP", _SC_CAP},
4559#endif
Fred Drakec9680921999-12-13 16:37:25 +00004560#ifdef _SC_CHARCLASS_NAME_MAX
4561 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4562#endif
4563#ifdef _SC_CHAR_BIT
4564 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4565#endif
4566#ifdef _SC_CHAR_MAX
4567 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4568#endif
4569#ifdef _SC_CHAR_MIN
4570 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4571#endif
4572#ifdef _SC_CHILD_MAX
4573 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4574#endif
4575#ifdef _SC_CLK_TCK
4576 {"SC_CLK_TCK", _SC_CLK_TCK},
4577#endif
4578#ifdef _SC_COHER_BLKSZ
4579 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4580#endif
4581#ifdef _SC_COLL_WEIGHTS_MAX
4582 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4583#endif
4584#ifdef _SC_DCACHE_ASSOC
4585 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4586#endif
4587#ifdef _SC_DCACHE_BLKSZ
4588 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4589#endif
4590#ifdef _SC_DCACHE_LINESZ
4591 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4592#endif
4593#ifdef _SC_DCACHE_SZ
4594 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4595#endif
4596#ifdef _SC_DCACHE_TBLKSZ
4597 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4598#endif
4599#ifdef _SC_DELAYTIMER_MAX
4600 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4601#endif
4602#ifdef _SC_EQUIV_CLASS_MAX
4603 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4604#endif
4605#ifdef _SC_EXPR_NEST_MAX
4606 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4607#endif
4608#ifdef _SC_FSYNC
4609 {"SC_FSYNC", _SC_FSYNC},
4610#endif
4611#ifdef _SC_GETGR_R_SIZE_MAX
4612 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4613#endif
4614#ifdef _SC_GETPW_R_SIZE_MAX
4615 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4616#endif
4617#ifdef _SC_ICACHE_ASSOC
4618 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4619#endif
4620#ifdef _SC_ICACHE_BLKSZ
4621 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4622#endif
4623#ifdef _SC_ICACHE_LINESZ
4624 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4625#endif
4626#ifdef _SC_ICACHE_SZ
4627 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4628#endif
Fred Draked86ed291999-12-15 15:34:33 +00004629#ifdef _SC_INF
4630 {"SC_INF", _SC_INF},
4631#endif
Fred Drakec9680921999-12-13 16:37:25 +00004632#ifdef _SC_INT_MAX
4633 {"SC_INT_MAX", _SC_INT_MAX},
4634#endif
4635#ifdef _SC_INT_MIN
4636 {"SC_INT_MIN", _SC_INT_MIN},
4637#endif
4638#ifdef _SC_IOV_MAX
4639 {"SC_IOV_MAX", _SC_IOV_MAX},
4640#endif
Fred Draked86ed291999-12-15 15:34:33 +00004641#ifdef _SC_IP_SECOPTS
4642 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4643#endif
Fred Drakec9680921999-12-13 16:37:25 +00004644#ifdef _SC_JOB_CONTROL
4645 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4646#endif
Fred Draked86ed291999-12-15 15:34:33 +00004647#ifdef _SC_KERN_POINTERS
4648 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4649#endif
4650#ifdef _SC_KERN_SIM
4651 {"SC_KERN_SIM", _SC_KERN_SIM},
4652#endif
Fred Drakec9680921999-12-13 16:37:25 +00004653#ifdef _SC_LINE_MAX
4654 {"SC_LINE_MAX", _SC_LINE_MAX},
4655#endif
4656#ifdef _SC_LOGIN_NAME_MAX
4657 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4658#endif
4659#ifdef _SC_LOGNAME_MAX
4660 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4661#endif
4662#ifdef _SC_LONG_BIT
4663 {"SC_LONG_BIT", _SC_LONG_BIT},
4664#endif
Fred Draked86ed291999-12-15 15:34:33 +00004665#ifdef _SC_MAC
4666 {"SC_MAC", _SC_MAC},
4667#endif
Fred Drakec9680921999-12-13 16:37:25 +00004668#ifdef _SC_MAPPED_FILES
4669 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4670#endif
4671#ifdef _SC_MAXPID
4672 {"SC_MAXPID", _SC_MAXPID},
4673#endif
4674#ifdef _SC_MB_LEN_MAX
4675 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4676#endif
4677#ifdef _SC_MEMLOCK
4678 {"SC_MEMLOCK", _SC_MEMLOCK},
4679#endif
4680#ifdef _SC_MEMLOCK_RANGE
4681 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4682#endif
4683#ifdef _SC_MEMORY_PROTECTION
4684 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4685#endif
4686#ifdef _SC_MESSAGE_PASSING
4687 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4688#endif
Fred Draked86ed291999-12-15 15:34:33 +00004689#ifdef _SC_MMAP_FIXED_ALIGNMENT
4690 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4691#endif
Fred Drakec9680921999-12-13 16:37:25 +00004692#ifdef _SC_MQ_OPEN_MAX
4693 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4694#endif
4695#ifdef _SC_MQ_PRIO_MAX
4696 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4697#endif
Fred Draked86ed291999-12-15 15:34:33 +00004698#ifdef _SC_NACLS_MAX
4699 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4700#endif
Fred Drakec9680921999-12-13 16:37:25 +00004701#ifdef _SC_NGROUPS_MAX
4702 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4703#endif
4704#ifdef _SC_NL_ARGMAX
4705 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4706#endif
4707#ifdef _SC_NL_LANGMAX
4708 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4709#endif
4710#ifdef _SC_NL_MSGMAX
4711 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4712#endif
4713#ifdef _SC_NL_NMAX
4714 {"SC_NL_NMAX", _SC_NL_NMAX},
4715#endif
4716#ifdef _SC_NL_SETMAX
4717 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4718#endif
4719#ifdef _SC_NL_TEXTMAX
4720 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4721#endif
4722#ifdef _SC_NPROCESSORS_CONF
4723 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4724#endif
4725#ifdef _SC_NPROCESSORS_ONLN
4726 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4727#endif
Fred Draked86ed291999-12-15 15:34:33 +00004728#ifdef _SC_NPROC_CONF
4729 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4730#endif
4731#ifdef _SC_NPROC_ONLN
4732 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4733#endif
Fred Drakec9680921999-12-13 16:37:25 +00004734#ifdef _SC_NZERO
4735 {"SC_NZERO", _SC_NZERO},
4736#endif
4737#ifdef _SC_OPEN_MAX
4738 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4739#endif
4740#ifdef _SC_PAGESIZE
4741 {"SC_PAGESIZE", _SC_PAGESIZE},
4742#endif
4743#ifdef _SC_PAGE_SIZE
4744 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4745#endif
4746#ifdef _SC_PASS_MAX
4747 {"SC_PASS_MAX", _SC_PASS_MAX},
4748#endif
4749#ifdef _SC_PHYS_PAGES
4750 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
4751#endif
4752#ifdef _SC_PII
4753 {"SC_PII", _SC_PII},
4754#endif
4755#ifdef _SC_PII_INTERNET
4756 {"SC_PII_INTERNET", _SC_PII_INTERNET},
4757#endif
4758#ifdef _SC_PII_INTERNET_DGRAM
4759 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
4760#endif
4761#ifdef _SC_PII_INTERNET_STREAM
4762 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
4763#endif
4764#ifdef _SC_PII_OSI
4765 {"SC_PII_OSI", _SC_PII_OSI},
4766#endif
4767#ifdef _SC_PII_OSI_CLTS
4768 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
4769#endif
4770#ifdef _SC_PII_OSI_COTS
4771 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
4772#endif
4773#ifdef _SC_PII_OSI_M
4774 {"SC_PII_OSI_M", _SC_PII_OSI_M},
4775#endif
4776#ifdef _SC_PII_SOCKET
4777 {"SC_PII_SOCKET", _SC_PII_SOCKET},
4778#endif
4779#ifdef _SC_PII_XTI
4780 {"SC_PII_XTI", _SC_PII_XTI},
4781#endif
4782#ifdef _SC_POLL
4783 {"SC_POLL", _SC_POLL},
4784#endif
4785#ifdef _SC_PRIORITIZED_IO
4786 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
4787#endif
4788#ifdef _SC_PRIORITY_SCHEDULING
4789 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
4790#endif
4791#ifdef _SC_REALTIME_SIGNALS
4792 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
4793#endif
4794#ifdef _SC_RE_DUP_MAX
4795 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
4796#endif
4797#ifdef _SC_RTSIG_MAX
4798 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
4799#endif
4800#ifdef _SC_SAVED_IDS
4801 {"SC_SAVED_IDS", _SC_SAVED_IDS},
4802#endif
4803#ifdef _SC_SCHAR_MAX
4804 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
4805#endif
4806#ifdef _SC_SCHAR_MIN
4807 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
4808#endif
4809#ifdef _SC_SELECT
4810 {"SC_SELECT", _SC_SELECT},
4811#endif
4812#ifdef _SC_SEMAPHORES
4813 {"SC_SEMAPHORES", _SC_SEMAPHORES},
4814#endif
4815#ifdef _SC_SEM_NSEMS_MAX
4816 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
4817#endif
4818#ifdef _SC_SEM_VALUE_MAX
4819 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
4820#endif
4821#ifdef _SC_SHARED_MEMORY_OBJECTS
4822 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
4823#endif
4824#ifdef _SC_SHRT_MAX
4825 {"SC_SHRT_MAX", _SC_SHRT_MAX},
4826#endif
4827#ifdef _SC_SHRT_MIN
4828 {"SC_SHRT_MIN", _SC_SHRT_MIN},
4829#endif
4830#ifdef _SC_SIGQUEUE_MAX
4831 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
4832#endif
4833#ifdef _SC_SIGRT_MAX
4834 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
4835#endif
4836#ifdef _SC_SIGRT_MIN
4837 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
4838#endif
Fred Draked86ed291999-12-15 15:34:33 +00004839#ifdef _SC_SOFTPOWER
4840 {"SC_SOFTPOWER", _SC_SOFTPOWER},
4841#endif
Fred Drakec9680921999-12-13 16:37:25 +00004842#ifdef _SC_SPLIT_CACHE
4843 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
4844#endif
4845#ifdef _SC_SSIZE_MAX
4846 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
4847#endif
4848#ifdef _SC_STACK_PROT
4849 {"SC_STACK_PROT", _SC_STACK_PROT},
4850#endif
4851#ifdef _SC_STREAM_MAX
4852 {"SC_STREAM_MAX", _SC_STREAM_MAX},
4853#endif
4854#ifdef _SC_SYNCHRONIZED_IO
4855 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
4856#endif
4857#ifdef _SC_THREADS
4858 {"SC_THREADS", _SC_THREADS},
4859#endif
4860#ifdef _SC_THREAD_ATTR_STACKADDR
4861 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
4862#endif
4863#ifdef _SC_THREAD_ATTR_STACKSIZE
4864 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
4865#endif
4866#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4867 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
4868#endif
4869#ifdef _SC_THREAD_KEYS_MAX
4870 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
4871#endif
4872#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4873 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
4874#endif
4875#ifdef _SC_THREAD_PRIO_INHERIT
4876 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
4877#endif
4878#ifdef _SC_THREAD_PRIO_PROTECT
4879 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
4880#endif
4881#ifdef _SC_THREAD_PROCESS_SHARED
4882 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
4883#endif
4884#ifdef _SC_THREAD_SAFE_FUNCTIONS
4885 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
4886#endif
4887#ifdef _SC_THREAD_STACK_MIN
4888 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
4889#endif
4890#ifdef _SC_THREAD_THREADS_MAX
4891 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
4892#endif
4893#ifdef _SC_TIMERS
4894 {"SC_TIMERS", _SC_TIMERS},
4895#endif
4896#ifdef _SC_TIMER_MAX
4897 {"SC_TIMER_MAX", _SC_TIMER_MAX},
4898#endif
4899#ifdef _SC_TTY_NAME_MAX
4900 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
4901#endif
4902#ifdef _SC_TZNAME_MAX
4903 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
4904#endif
4905#ifdef _SC_T_IOV_MAX
4906 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
4907#endif
4908#ifdef _SC_UCHAR_MAX
4909 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
4910#endif
4911#ifdef _SC_UINT_MAX
4912 {"SC_UINT_MAX", _SC_UINT_MAX},
4913#endif
4914#ifdef _SC_UIO_MAXIOV
4915 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
4916#endif
4917#ifdef _SC_ULONG_MAX
4918 {"SC_ULONG_MAX", _SC_ULONG_MAX},
4919#endif
4920#ifdef _SC_USHRT_MAX
4921 {"SC_USHRT_MAX", _SC_USHRT_MAX},
4922#endif
4923#ifdef _SC_VERSION
4924 {"SC_VERSION", _SC_VERSION},
4925#endif
4926#ifdef _SC_WORD_BIT
4927 {"SC_WORD_BIT", _SC_WORD_BIT},
4928#endif
4929#ifdef _SC_XBS5_ILP32_OFF32
4930 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
4931#endif
4932#ifdef _SC_XBS5_ILP32_OFFBIG
4933 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
4934#endif
4935#ifdef _SC_XBS5_LP64_OFF64
4936 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
4937#endif
4938#ifdef _SC_XBS5_LPBIG_OFFBIG
4939 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
4940#endif
4941#ifdef _SC_XOPEN_CRYPT
4942 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
4943#endif
4944#ifdef _SC_XOPEN_ENH_I18N
4945 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
4946#endif
4947#ifdef _SC_XOPEN_LEGACY
4948 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
4949#endif
4950#ifdef _SC_XOPEN_REALTIME
4951 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
4952#endif
4953#ifdef _SC_XOPEN_REALTIME_THREADS
4954 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
4955#endif
4956#ifdef _SC_XOPEN_SHM
4957 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
4958#endif
4959#ifdef _SC_XOPEN_UNIX
4960 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
4961#endif
4962#ifdef _SC_XOPEN_VERSION
4963 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
4964#endif
4965#ifdef _SC_XOPEN_XCU_VERSION
4966 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
4967#endif
4968#ifdef _SC_XOPEN_XPG2
4969 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
4970#endif
4971#ifdef _SC_XOPEN_XPG3
4972 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
4973#endif
4974#ifdef _SC_XOPEN_XPG4
4975 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
4976#endif
4977};
4978
4979static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004980conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004981{
4982 return conv_confname(arg, valuep, posix_constants_sysconf,
4983 sizeof(posix_constants_sysconf)
4984 / sizeof(struct constdef));
4985}
4986
4987static char posix_sysconf__doc__[] = "\
4988sysconf(name) -> integer\n\
4989Return an integer-valued system configuration variable.";
4990
4991static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004992posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004993{
4994 PyObject *result = NULL;
4995 int name;
4996
4997 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
4998 int value;
4999
5000 errno = 0;
5001 value = sysconf(name);
5002 if (value == -1 && errno != 0)
5003 posix_error();
5004 else
5005 result = PyInt_FromLong(value);
5006 }
5007 return result;
5008}
5009#endif
5010
5011
Fred Drakebec628d1999-12-15 18:31:10 +00005012/* This code is used to ensure that the tables of configuration value names
5013 * are in sorted order as required by conv_confname(), and also to build the
5014 * the exported dictionaries that are used to publish information about the
5015 * names available on the host platform.
5016 *
5017 * Sorting the table at runtime ensures that the table is properly ordered
5018 * when used, even for platforms we're not able to test on. It also makes
5019 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005020 */
Fred Drakebec628d1999-12-15 18:31:10 +00005021
5022static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005023cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005024{
5025 const struct constdef *c1 =
5026 (const struct constdef *) v1;
5027 const struct constdef *c2 =
5028 (const struct constdef *) v2;
5029
5030 return strcmp(c1->name, c2->name);
5031}
5032
5033static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005034setup_confname_table(struct constdef *table, size_t tablesize,
5035 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005036{
Fred Drakebec628d1999-12-15 18:31:10 +00005037 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005038 size_t i;
5039 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005040
5041 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5042 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005043 if (d == NULL)
5044 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005045
Barry Warsaw3155db32000-04-13 15:20:40 +00005046 for (i=0; i < tablesize; ++i) {
5047 PyObject *o = PyInt_FromLong(table[i].value);
5048 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5049 Py_XDECREF(o);
5050 Py_DECREF(d);
5051 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005052 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005053 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005054 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005055 status = PyDict_SetItemString(moddict, tablename, d);
5056 Py_DECREF(d);
5057 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005058}
5059
Fred Drakebec628d1999-12-15 18:31:10 +00005060/* Return -1 on failure, 0 on success. */
5061static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005062setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005063{
5064#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005065 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005066 sizeof(posix_constants_pathconf)
5067 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005068 "pathconf_names", moddict))
5069 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005070#endif
5071#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005072 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005073 sizeof(posix_constants_confstr)
5074 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005075 "confstr_names", moddict))
5076 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005077#endif
5078#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005079 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005080 sizeof(posix_constants_sysconf)
5081 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005082 "sysconf_names", moddict))
5083 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005084#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005085 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005086}
Fred Draked86ed291999-12-15 15:34:33 +00005087
5088
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005089static char posix_abort__doc__[] = "\
5090abort() -> does not return!\n\
5091Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5092in the hardest way possible on the hosting operating system.";
5093
5094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005095posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005096{
5097 if (!PyArg_ParseTuple(args, ":abort"))
5098 return NULL;
5099 abort();
5100 /*NOTREACHED*/
5101 Py_FatalError("abort() called from Python code didn't abort!");
5102 return NULL;
5103}
Fred Drakebec628d1999-12-15 18:31:10 +00005104
Tim Petersf58a7aa2000-09-22 10:05:54 +00005105#ifdef MS_WIN32
5106static char win32_startfile__doc__[] = "\
5107startfile(filepath) - Start a file with its associated application.\n\
5108\n\
5109This acts like double-clicking the file in Explorer, or giving the file\n\
5110name as an argument to the DOS \"start\" command: the file is opened\n\
5111with whatever application (if any) its extension is associated.\n\
5112\n\
5113startfile returns as soon as the associated application is launched.\n\
5114There is no option to wait for the application to close, and no way\n\
5115to retrieve the application's exit status.\n\
5116\n\
5117The filepath is relative to the current directory. If you want to use\n\
5118an absolute path, make sure the first character is not a slash (\"/\");\n\
5119the underlying Win32 ShellExecute function doesn't work if it is.";
5120
5121static PyObject *
5122win32_startfile(PyObject *self, PyObject *args)
5123{
5124 char *filepath;
5125 HINSTANCE rc;
5126 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5127 return NULL;
5128 Py_BEGIN_ALLOW_THREADS
5129 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5130 Py_END_ALLOW_THREADS
5131 if (rc <= (HINSTANCE)32)
5132 return win32_error("startfile", filepath);
5133 Py_INCREF(Py_None);
5134 return Py_None;
5135}
5136#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005137
5138static PyMethodDef posix_methods[] = {
5139 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5140#ifdef HAVE_TTYNAME
5141 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5142#endif
5143 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5144 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005145#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005146 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005147#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005148#ifdef HAVE_CTERMID
5149 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5150#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005151#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005152 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005153#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005154#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005155 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005156#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005157 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5158 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5159 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005160#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005161 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005162#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005163#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005164 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005165#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005166 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5167 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5168 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005169#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005170 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005171#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005172#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005173 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005174#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005175 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005176#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005177 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005178#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005179 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5180 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5181 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005182#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005183 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005184#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005185 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005186#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005187 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5188 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005189#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005190#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005191 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5192 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005193#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005194#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005195 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005196#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005197#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005198 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005199#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005200#ifdef HAVE_FORKPTY
5201 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5202#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005203#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005204 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005205#endif /* HAVE_GETEGID */
5206#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005207 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005208#endif /* HAVE_GETEUID */
5209#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005210 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005211#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005212#ifdef HAVE_GETGROUPS
5213 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5214#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005215 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005216#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005217 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005218#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005219#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005220 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005221#endif /* HAVE_GETPPID */
5222#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005223 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005224#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005225#ifdef HAVE_GETLOGIN
5226 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5227#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005228#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005229 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005230#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005231#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005232 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005233#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005234#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005235 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005236#ifdef MS_WIN32
5237 {"popen2", win32_popen2, METH_VARARGS},
5238 {"popen3", win32_popen3, METH_VARARGS},
5239 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005240 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005241#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005242#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005243#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005244 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005245#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005246#ifdef HAVE_SETEUID
5247 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5248#endif /* HAVE_SETEUID */
5249#ifdef HAVE_SETEGID
5250 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5251#endif /* HAVE_SETEGID */
5252#ifdef HAVE_SETREUID
5253 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5254#endif /* HAVE_SETREUID */
5255#ifdef HAVE_SETREGID
5256 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5257#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005258#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005259 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005260#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005261#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005262 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005263#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005264#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005265 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005266#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005267#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005268 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005269#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005270#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005271 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005272#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005273#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005274 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005275#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005276#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005277 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005278#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005279#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005280 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005281#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005282 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5283 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5284 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5285 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5286 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5287 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5288 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5289 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5290 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005291 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005292#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005293 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005294#endif
5295#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005296 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005297#endif
5298#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005299 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005300#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005301#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005302 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005303#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005304#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005305 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005306#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005307#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005308 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005309#endif
5310#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005311 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005312#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005313#ifdef HAVE_SYS_WAIT_H
5314#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005315 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005316#endif /* WIFSTOPPED */
5317#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005318 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005319#endif /* WIFSIGNALED */
5320#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005321 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005322#endif /* WIFEXITED */
5323#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005324 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005325#endif /* WEXITSTATUS */
5326#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005327 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005328#endif /* WTERMSIG */
5329#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005330 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005331#endif /* WSTOPSIG */
5332#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005333#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005334 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005335#endif
5336#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005337 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005338#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005339#ifdef HAVE_TMPNAM
5340 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5341#endif
5342#ifdef HAVE_TEMPNAM
5343 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5344#endif
5345#ifdef HAVE_TMPNAM
5346 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5347#endif
Fred Drakec9680921999-12-13 16:37:25 +00005348#ifdef HAVE_CONFSTR
5349 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5350#endif
5351#ifdef HAVE_SYSCONF
5352 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5353#endif
5354#ifdef HAVE_FPATHCONF
5355 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5356#endif
5357#ifdef HAVE_PATHCONF
5358 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5359#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005360 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005361 {NULL, NULL} /* Sentinel */
5362};
5363
5364
Barry Warsaw4a342091996-12-19 23:50:02 +00005365static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005366ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005367{
5368 PyObject* v = PyInt_FromLong(value);
5369 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5370 return -1; /* triggers fatal error */
5371
5372 Py_DECREF(v);
5373 return 0;
5374}
5375
Guido van Rossumd48f2521997-12-05 22:19:34 +00005376#if defined(PYOS_OS2)
5377/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5378static int insertvalues(PyObject *d)
5379{
5380 APIRET rc;
5381 ULONG values[QSV_MAX+1];
5382 PyObject *v;
5383 char *ver, tmp[10];
5384
5385 Py_BEGIN_ALLOW_THREADS
5386 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5387 Py_END_ALLOW_THREADS
5388
5389 if (rc != NO_ERROR) {
5390 os2_error(rc);
5391 return -1;
5392 }
5393
5394 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5395 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5396 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5397 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5398 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5399 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5400 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5401
5402 switch (values[QSV_VERSION_MINOR]) {
5403 case 0: ver = "2.00"; break;
5404 case 10: ver = "2.10"; break;
5405 case 11: ver = "2.11"; break;
5406 case 30: ver = "3.00"; break;
5407 case 40: ver = "4.00"; break;
5408 case 50: ver = "5.00"; break;
5409 default:
5410 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5411 values[QSV_VERSION_MINOR]);
5412 ver = &tmp[0];
5413 }
5414
5415 /* Add Indicator of the Version of the Operating System */
5416 v = PyString_FromString(ver);
5417 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5418 return -1;
5419 Py_DECREF(v);
5420
5421 /* Add Indicator of Which Drive was Used to Boot the System */
5422 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5423 tmp[1] = ':';
5424 tmp[2] = '\0';
5425
5426 v = PyString_FromString(tmp);
5427 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5428 return -1;
5429 Py_DECREF(v);
5430
5431 return 0;
5432}
5433#endif
5434
Barry Warsaw4a342091996-12-19 23:50:02 +00005435static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005436all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005437{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005438#ifdef F_OK
5439 if (ins(d, "F_OK", (long)F_OK)) return -1;
5440#endif
5441#ifdef R_OK
5442 if (ins(d, "R_OK", (long)R_OK)) return -1;
5443#endif
5444#ifdef W_OK
5445 if (ins(d, "W_OK", (long)W_OK)) return -1;
5446#endif
5447#ifdef X_OK
5448 if (ins(d, "X_OK", (long)X_OK)) return -1;
5449#endif
Fred Drakec9680921999-12-13 16:37:25 +00005450#ifdef NGROUPS_MAX
5451 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5452#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005453#ifdef TMP_MAX
5454 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5455#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005456#ifdef WNOHANG
5457 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5458#endif
5459#ifdef O_RDONLY
5460 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5461#endif
5462#ifdef O_WRONLY
5463 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5464#endif
5465#ifdef O_RDWR
5466 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5467#endif
5468#ifdef O_NDELAY
5469 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5470#endif
5471#ifdef O_NONBLOCK
5472 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5473#endif
5474#ifdef O_APPEND
5475 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5476#endif
5477#ifdef O_DSYNC
5478 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5479#endif
5480#ifdef O_RSYNC
5481 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5482#endif
5483#ifdef O_SYNC
5484 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5485#endif
5486#ifdef O_NOCTTY
5487 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5488#endif
5489#ifdef O_CREAT
5490 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5491#endif
5492#ifdef O_EXCL
5493 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5494#endif
5495#ifdef O_TRUNC
5496 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5497#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005498#ifdef O_BINARY
5499 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5500#endif
5501#ifdef O_TEXT
5502 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5503#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005504
Guido van Rossum246bc171999-02-01 23:54:31 +00005505#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005506 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5507 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5508 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5509 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5510 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005511#endif
5512
Guido van Rossumd48f2521997-12-05 22:19:34 +00005513#if defined(PYOS_OS2)
5514 if (insertvalues(d)) return -1;
5515#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005516 return 0;
5517}
5518
5519
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005520#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005521#define INITFUNC initnt
5522#define MODNAME "nt"
5523#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005524#if defined(PYOS_OS2)
5525#define INITFUNC initos2
5526#define MODNAME "os2"
5527#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005528#define INITFUNC initposix
5529#define MODNAME "posix"
5530#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005531#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005532
Guido van Rossum3886bb61998-12-04 18:50:17 +00005533DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005534INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005535{
Barry Warsaw53699e91996-12-10 23:23:01 +00005536 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005537
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005538 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005539 posix_methods,
5540 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005541 (PyObject *)NULL,
5542 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005543 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005544
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005545 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005546 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005547 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005548 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005549 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005550
Barry Warsaw4a342091996-12-19 23:50:02 +00005551 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005552 return;
5553
Fred Drakebec628d1999-12-15 18:31:10 +00005554 if (setup_confname_tables(d))
5555 return;
5556
Barry Warsawca74da41999-02-09 19:31:45 +00005557 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005558
Guido van Rossumb3d39562000-01-31 18:41:26 +00005559#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005560 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005561#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005562}