blob: e46d68a8e0053030af8e8385893e127c7cf98922 [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
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005105
5106static PyMethodDef posix_methods[] = {
5107 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5108#ifdef HAVE_TTYNAME
5109 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5110#endif
5111 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5112 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005113#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005114 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005115#endif /* HAVE_CHOWN */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005116#ifdef HAVE_CTERMID
5117 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5118#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005119#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005120 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005121#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005122#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005123 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005124#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005125 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5126 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5127 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005128#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005129 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005130#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005131#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005132 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005133#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005134 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5135 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5136 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005137#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005138 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005139#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005140#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005141 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005142#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005143 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005144#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005145 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005146#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005147 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5148 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5149 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005150#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005151 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005152#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005153 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005154#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005155 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5156 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005157#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005158#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005159 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5160 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005161#endif /* HAVE_SPAWNV */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005162#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005163 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005164#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005165#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005166 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005167#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005168#ifdef HAVE_FORKPTY
5169 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5170#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005171#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005172 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005173#endif /* HAVE_GETEGID */
5174#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005175 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005176#endif /* HAVE_GETEUID */
5177#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005178 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005179#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005180#ifdef HAVE_GETGROUPS
5181 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5182#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005183 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005184#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005185 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005186#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005187#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005188 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005189#endif /* HAVE_GETPPID */
5190#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005191 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005192#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005193#ifdef HAVE_GETLOGIN
5194 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5195#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005196#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005197 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005198#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005199#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005200 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005201#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005202#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005203 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005204#ifdef MS_WIN32
5205 {"popen2", win32_popen2, METH_VARARGS},
5206 {"popen3", win32_popen3, METH_VARARGS},
5207 {"popen4", win32_popen4, METH_VARARGS},
5208#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005209#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005210#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005211 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005212#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005213#ifdef HAVE_SETEUID
5214 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5215#endif /* HAVE_SETEUID */
5216#ifdef HAVE_SETEGID
5217 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5218#endif /* HAVE_SETEGID */
5219#ifdef HAVE_SETREUID
5220 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5221#endif /* HAVE_SETREUID */
5222#ifdef HAVE_SETREGID
5223 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5224#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005225#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005226 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005227#endif /* HAVE_SETGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005228#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005229 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005230#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005231#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005232 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005233#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005234#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005235 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005236#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005237#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005238 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005239#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005240#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005241 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005242#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005243#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005244 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005245#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005246#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005247 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005248#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005249 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5250 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5251 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5252 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5253 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5254 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5255 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5256 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5257 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005258 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005259#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005260 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005261#endif
5262#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005263 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005264#endif
5265#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005266 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005267#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005268#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005269 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005270#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005271#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005272 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005273#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005274#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005275 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005276#endif
5277#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005278 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005279#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005280#ifdef HAVE_SYS_WAIT_H
5281#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005282 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005283#endif /* WIFSTOPPED */
5284#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005285 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005286#endif /* WIFSIGNALED */
5287#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005288 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005289#endif /* WIFEXITED */
5290#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005291 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005292#endif /* WEXITSTATUS */
5293#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005294 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005295#endif /* WTERMSIG */
5296#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005297 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005298#endif /* WSTOPSIG */
5299#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005300#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005301 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005302#endif
5303#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005304 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005305#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005306#ifdef HAVE_TMPNAM
5307 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5308#endif
5309#ifdef HAVE_TEMPNAM
5310 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5311#endif
5312#ifdef HAVE_TMPNAM
5313 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5314#endif
Fred Drakec9680921999-12-13 16:37:25 +00005315#ifdef HAVE_CONFSTR
5316 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5317#endif
5318#ifdef HAVE_SYSCONF
5319 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5320#endif
5321#ifdef HAVE_FPATHCONF
5322 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5323#endif
5324#ifdef HAVE_PATHCONF
5325 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5326#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005327 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005328 {NULL, NULL} /* Sentinel */
5329};
5330
5331
Barry Warsaw4a342091996-12-19 23:50:02 +00005332static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005333ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005334{
5335 PyObject* v = PyInt_FromLong(value);
5336 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5337 return -1; /* triggers fatal error */
5338
5339 Py_DECREF(v);
5340 return 0;
5341}
5342
Guido van Rossumd48f2521997-12-05 22:19:34 +00005343#if defined(PYOS_OS2)
5344/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5345static int insertvalues(PyObject *d)
5346{
5347 APIRET rc;
5348 ULONG values[QSV_MAX+1];
5349 PyObject *v;
5350 char *ver, tmp[10];
5351
5352 Py_BEGIN_ALLOW_THREADS
5353 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5354 Py_END_ALLOW_THREADS
5355
5356 if (rc != NO_ERROR) {
5357 os2_error(rc);
5358 return -1;
5359 }
5360
5361 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5362 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5363 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5364 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5365 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5366 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5367 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5368
5369 switch (values[QSV_VERSION_MINOR]) {
5370 case 0: ver = "2.00"; break;
5371 case 10: ver = "2.10"; break;
5372 case 11: ver = "2.11"; break;
5373 case 30: ver = "3.00"; break;
5374 case 40: ver = "4.00"; break;
5375 case 50: ver = "5.00"; break;
5376 default:
5377 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5378 values[QSV_VERSION_MINOR]);
5379 ver = &tmp[0];
5380 }
5381
5382 /* Add Indicator of the Version of the Operating System */
5383 v = PyString_FromString(ver);
5384 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5385 return -1;
5386 Py_DECREF(v);
5387
5388 /* Add Indicator of Which Drive was Used to Boot the System */
5389 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5390 tmp[1] = ':';
5391 tmp[2] = '\0';
5392
5393 v = PyString_FromString(tmp);
5394 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5395 return -1;
5396 Py_DECREF(v);
5397
5398 return 0;
5399}
5400#endif
5401
Barry Warsaw4a342091996-12-19 23:50:02 +00005402static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005403all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005404{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005405#ifdef F_OK
5406 if (ins(d, "F_OK", (long)F_OK)) return -1;
5407#endif
5408#ifdef R_OK
5409 if (ins(d, "R_OK", (long)R_OK)) return -1;
5410#endif
5411#ifdef W_OK
5412 if (ins(d, "W_OK", (long)W_OK)) return -1;
5413#endif
5414#ifdef X_OK
5415 if (ins(d, "X_OK", (long)X_OK)) return -1;
5416#endif
Fred Drakec9680921999-12-13 16:37:25 +00005417#ifdef NGROUPS_MAX
5418 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5419#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005420#ifdef TMP_MAX
5421 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5422#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005423#ifdef WNOHANG
5424 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5425#endif
5426#ifdef O_RDONLY
5427 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5428#endif
5429#ifdef O_WRONLY
5430 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5431#endif
5432#ifdef O_RDWR
5433 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5434#endif
5435#ifdef O_NDELAY
5436 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5437#endif
5438#ifdef O_NONBLOCK
5439 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5440#endif
5441#ifdef O_APPEND
5442 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5443#endif
5444#ifdef O_DSYNC
5445 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5446#endif
5447#ifdef O_RSYNC
5448 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5449#endif
5450#ifdef O_SYNC
5451 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5452#endif
5453#ifdef O_NOCTTY
5454 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5455#endif
5456#ifdef O_CREAT
5457 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5458#endif
5459#ifdef O_EXCL
5460 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5461#endif
5462#ifdef O_TRUNC
5463 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5464#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005465#ifdef O_BINARY
5466 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5467#endif
5468#ifdef O_TEXT
5469 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5470#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005471
Guido van Rossum246bc171999-02-01 23:54:31 +00005472#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005473 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5474 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5475 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5476 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5477 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005478#endif
5479
Guido van Rossumd48f2521997-12-05 22:19:34 +00005480#if defined(PYOS_OS2)
5481 if (insertvalues(d)) return -1;
5482#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005483 return 0;
5484}
5485
5486
Guido van Rossumc5a0f531997-12-02 20:36:02 +00005487#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005488#define INITFUNC initnt
5489#define MODNAME "nt"
5490#else
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005491#if defined(PYOS_OS2)
5492#define INITFUNC initos2
5493#define MODNAME "os2"
5494#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005495#define INITFUNC initposix
5496#define MODNAME "posix"
5497#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005498#endif
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005499
Guido van Rossum3886bb61998-12-04 18:50:17 +00005500DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005501INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005502{
Barry Warsaw53699e91996-12-10 23:23:01 +00005503 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005504
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005505 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005506 posix_methods,
5507 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005508 (PyObject *)NULL,
5509 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005510 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005511
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005512 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005513 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005514 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005515 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005516 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005517
Barry Warsaw4a342091996-12-19 23:50:02 +00005518 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005519 return;
5520
Fred Drakebec628d1999-12-15 18:31:10 +00005521 if (setup_confname_tables(d))
5522 return;
5523
Barry Warsawca74da41999-02-09 19:31:45 +00005524 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005525
Guido van Rossumb3d39562000-01-31 18:41:26 +00005526#ifdef HAVE_PUTENV
Fred Drake762e2061999-08-26 17:23:54 +00005527 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005528#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005529}