blob: 346de544f5f449e05146280e538b689c77688af4 [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 Rossuma6535fd2001-10-18 19:44:10 +000031
Guido van Rossum36bc6801995-06-14 22:54:23 +000032#ifdef HAVE_SYS_WAIT_H
33#include <sys/wait.h> /* For WNOHANG */
34#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000035
Guido van Rossuma376cc51996-12-05 23:43:35 +000036#ifdef HAVE_SIGNAL_H
37#include <signal.h>
38#endif
39
Guido van Rossumb6775db1994-08-01 11:34:53 +000040#ifdef HAVE_FCNTL_H
41#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000042#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000043
Guido van Rossuma6535fd2001-10-18 19:44:10 +000044#ifdef HAVE_GRP_H
45#include <grp.h>
46#endif
47
Skip Montanaro8216c182001-02-27 17:04:34 +000048/* pick up declaration of confstr on some systems? */
49#ifdef HAVE_UNISTD_H
50#include <unistd.h>
51#endif /* HAVE_UNISTD_H */
52
Guido van Rossuma4916fa1996-05-23 22:58:55 +000053/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000054/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000055#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000056#include <process.h>
57#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000058#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000059#define HAVE_GETCWD 1
60#define HAVE_OPENDIR 1
61#define HAVE_SYSTEM 1
62#if defined(__OS2__)
63#define HAVE_EXECV 1
64#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000065#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000066#include <process.h>
67#else
68#ifdef __BORLANDC__ /* Borland compiler */
69#define HAVE_EXECV 1
70#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000071#define HAVE_OPENDIR 1
72#define HAVE_PIPE 1
73#define HAVE_POPEN 1
74#define HAVE_SYSTEM 1
75#define HAVE_WAIT 1
76#else
77#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000078#define HAVE_GETCWD 1
79#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000080#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000081#define HAVE_EXECV 1
82#define HAVE_PIPE 1
83#define HAVE_POPEN 1
84#define HAVE_SYSTEM 1
85#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000086#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000087#else /* all other compilers */
88/* Unix functions that the configure script doesn't check for */
89#define HAVE_EXECV 1
90#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000091#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
92#define HAVE_FORK1 1
93#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#define HAVE_GETCWD 1
95#define HAVE_GETEGID 1
96#define HAVE_GETEUID 1
97#define HAVE_GETGID 1
98#define HAVE_GETPPID 1
99#define HAVE_GETUID 1
100#define HAVE_KILL 1
101#define HAVE_OPENDIR 1
102#define HAVE_PIPE 1
103#define HAVE_POPEN 1
104#define HAVE_SYSTEM 1
105#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000106#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000107#endif /* _MSC_VER */
108#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000109#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000110#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000113
Guido van Rossumb6775db1994-08-01 11:34:53 +0000114#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000115#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000116#endif
117
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000118#if defined(sun) && !defined(__SVR4)
119/* SunOS 4.1.4 doesn't have prototypes for these: */
120extern int rename(const char *, const char *);
121extern int pclose(FILE *);
122extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000123extern int fsync(int);
124extern int lstat(const char *, struct stat *);
125extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000126#endif
127
Guido van Rossum36bc6801995-06-14 22:54:23 +0000128#ifdef NeXT
129/* NeXT's <unistd.h> and <utime.h> aren't worth much */
130#undef HAVE_UNISTD_H
131#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000132#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000133/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000134#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000135#endif
136
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000137#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000138#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000139extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000140#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000141#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000142extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000144extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#endif
147#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000148extern int chdir(char *);
149extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000150#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000151extern int chdir(const char *);
152extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000153#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000154#ifdef __BORLANDC__
155extern int chmod(const char *, int);
156#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000158#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000159extern int chown(const char *, uid_t, gid_t);
160extern char *getcwd(char *, int);
161extern char *strerror(int);
162extern int link(const char *, const char *);
163extern int rename(const char *, const char *);
164extern int stat(const char *, struct stat *);
165extern int unlink(const char *);
166extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000167#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000168extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000169#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000170#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000171extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000172#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000173#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000174
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177#ifdef HAVE_UTIME_H
178#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000179#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000180
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000181#ifdef HAVE_SYS_UTIME_H
182#include <sys/utime.h>
183#define HAVE_UTIME_H /* pretend we do for the rest of this file */
184#endif /* HAVE_SYS_UTIME_H */
185
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186#ifdef HAVE_SYS_TIMES_H
187#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000188#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189
190#ifdef HAVE_SYS_PARAM_H
191#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000192#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000193
194#ifdef HAVE_SYS_UTSNAME_H
195#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000196#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197
198#ifndef MAXPATHLEN
199#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000200#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000202#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#define NAMLEN(dirent) strlen((dirent)->d_name)
205#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000206#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000207#include <direct.h>
208#define NAMLEN(dirent) strlen((dirent)->d_name)
209#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000210#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000211#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000212#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000213#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000218#endif
219#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000221#endif
222#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000224#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225#include <direct.h>
226#include <io.h>
227#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000228#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000230#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000231#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000232#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000233#else /* 16-bit Windows */
234#include <dos.h>
235#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000236#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000237#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238
Guido van Rossumd48f2521997-12-05 22:19:34 +0000239#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000241#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000243#ifdef UNION_WAIT
244/* Emulate some macros on systems that have a union instead of macros */
245
246#ifndef WIFEXITED
247#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
248#endif
249
250#ifndef WEXITSTATUS
251#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
252#endif
253
254#ifndef WTERMSIG
255#define WTERMSIG(u_wait) ((u_wait).w_termsig)
256#endif
257
258#endif /* UNION_WAIT */
259
Greg Wardb48bc172000-03-01 21:51:56 +0000260/* Don't use the "_r" form if we don't need it (also, won't have a
261 prototype for it, at least on Solaris -- maybe others as well?). */
262#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
263#define USE_CTERMID_R
264#endif
265
266#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
267#define USE_TMPNAM_R
268#endif
269
Fred Drake699f3522000-06-29 21:12:41 +0000270/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000271#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000272#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000273# define STAT _stati64
274# define FSTAT _fstati64
275# define STRUCT_STAT struct _stati64
276#else
277# define STAT stat
278# define FSTAT fstat
279# define STRUCT_STAT struct stat
280#endif
281
282
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283/* Return a dictionary corresponding to the POSIX environment table */
284
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000285#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000287#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288
Barry Warsaw53699e91996-12-10 23:23:01 +0000289static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000290convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291{
Barry Warsaw53699e91996-12-10 23:23:01 +0000292 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000294 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 if (d == NULL)
296 return NULL;
297 if (environ == NULL)
298 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000299 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000301 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000302 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000303 char *p = strchr(*e, '=');
304 if (p == NULL)
305 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000306 k = PyString_FromStringAndSize(*e, (int)(p-*e));
307 if (k == NULL) {
308 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000310 }
311 v = PyString_FromString(p+1);
312 if (v == NULL) {
313 PyErr_Clear();
314 Py_DECREF(k);
315 continue;
316 }
317 if (PyDict_GetItem(d, k) == NULL) {
318 if (PyDict_SetItem(d, k, v) != 0)
319 PyErr_Clear();
320 }
321 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000322 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000324#if defined(PYOS_OS2)
325 {
326 APIRET rc;
327 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
328
329 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000330 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000331 PyObject *v = PyString_FromString(buffer);
332 PyDict_SetItemString(d, "BEGINLIBPATH", v);
333 Py_DECREF(v);
334 }
335 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
336 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
337 PyObject *v = PyString_FromString(buffer);
338 PyDict_SetItemString(d, "ENDLIBPATH", v);
339 Py_DECREF(v);
340 }
341 }
342#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000343 return d;
344}
345
346
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347/* Set a POSIX-specific error from errno, and return NULL */
348
Barry Warsawd58d7641998-07-23 16:14:40 +0000349static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000350posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000351{
Barry Warsawca74da41999-02-09 19:31:45 +0000352 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000353}
Barry Warsawd58d7641998-07-23 16:14:40 +0000354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000355posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000356{
Barry Warsawca74da41999-02-09 19:31:45 +0000357 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000358}
359
Mark Hammondef8b6542001-05-13 08:04:26 +0000360static PyObject *
361posix_error_with_allocated_filename(char* name)
362{
363 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
364 PyMem_Free(name);
365 return rc;
366}
367
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000368#ifdef MS_WIN32
369static PyObject *
370win32_error(char* function, char* filename)
371{
Mark Hammond33a6da92000-08-15 00:46:38 +0000372 /* XXX We should pass the function name along in the future.
373 (_winreg.c also wants to pass the function name.)
374 This would however require an additional param to the
375 Windows error object, which is non-trivial.
376 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000377 errno = GetLastError();
378 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000379 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000380 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000381 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000382}
383#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000384
Guido van Rossumd48f2521997-12-05 22:19:34 +0000385#if defined(PYOS_OS2)
386/**********************************************************************
387 * Helper Function to Trim and Format OS/2 Messages
388 **********************************************************************/
389 static void
390os2_formatmsg(char *msgbuf, int msglen, char *reason)
391{
392 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
393
394 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
395 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
396
397 while (lastc > msgbuf && isspace(*lastc))
398 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
399 }
400
401 /* Add Optional Reason Text */
402 if (reason) {
403 strcat(msgbuf, " : ");
404 strcat(msgbuf, reason);
405 }
406}
407
408/**********************************************************************
409 * Decode an OS/2 Operating System Error Code
410 *
411 * A convenience function to lookup an OS/2 error code and return a
412 * text message we can use to raise a Python exception.
413 *
414 * Notes:
415 * The messages for errors returned from the OS/2 kernel reside in
416 * the file OSO001.MSG in the \OS2 directory hierarchy.
417 *
418 **********************************************************************/
419 static char *
420os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
421{
422 APIRET rc;
423 ULONG msglen;
424
425 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
426 Py_BEGIN_ALLOW_THREADS
427 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
428 errorcode, "oso001.msg", &msglen);
429 Py_END_ALLOW_THREADS
430
431 if (rc == NO_ERROR)
432 os2_formatmsg(msgbuf, msglen, reason);
433 else
434 sprintf(msgbuf, "unknown OS error #%d", errorcode);
435
436 return msgbuf;
437}
438
439/* Set an OS/2-specific error and return NULL. OS/2 kernel
440 errors are not in a global variable e.g. 'errno' nor are
441 they congruent with posix error numbers. */
442
443static PyObject * os2_error(int code)
444{
445 char text[1024];
446 PyObject *v;
447
448 os2_strerror(text, sizeof(text), code, "");
449
450 v = Py_BuildValue("(is)", code, text);
451 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000452 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000453 Py_DECREF(v);
454 }
455 return NULL; /* Signal to Python that an Exception is Pending */
456}
457
458#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000459
460/* POSIX generic methods */
461
Barry Warsaw53699e91996-12-10 23:23:01 +0000462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000463posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000464{
465 int fd;
466 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000467 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000468 return NULL;
469 Py_BEGIN_ALLOW_THREADS
470 res = (*func)(fd);
471 Py_END_ALLOW_THREADS
472 if (res < 0)
473 return posix_error();
474 Py_INCREF(Py_None);
475 return Py_None;
476}
477
478
479static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000480posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481{
Mark Hammondef8b6542001-05-13 08:04:26 +0000482 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000483 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000484 if (!PyArg_ParseTuple(args, format,
485 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000487 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000488 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000489 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000491 return posix_error_with_allocated_filename(path1);
492 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000493 Py_INCREF(Py_None);
494 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000495}
496
Barry Warsaw53699e91996-12-10 23:23:01 +0000497static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000498posix_2str(PyObject *args, char *format,
499 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500{
Mark Hammondef8b6542001-05-13 08:04:26 +0000501 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000502 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000503 if (!PyArg_ParseTuple(args, format,
504 Py_FileSystemDefaultEncoding, &path1,
505 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000506 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000507 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000508 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000509 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000510 PyMem_Free(path1);
511 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000512 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000513 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000514 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000515 Py_INCREF(Py_None);
516 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517}
518
Fred Drake699f3522000-06-29 21:12:41 +0000519/* pack a system stat C structure into the Python stat tuple
520 (used by posix_stat() and posix_fstat()) */
521static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000522_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000523{
524 PyObject *v = PyTuple_New(10);
525 if (v == NULL)
526 return NULL;
527
528 PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
529#ifdef HAVE_LARGEFILE_SUPPORT
530 PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
531#else
532 PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
533#endif
534#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
535 PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
536#else
537 PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
538#endif
539 PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
540 PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
541 PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
542#ifdef HAVE_LARGEFILE_SUPPORT
543 PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
544#else
545 PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
546#endif
547#if SIZEOF_TIME_T > SIZEOF_LONG
548 PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
549 PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
550 PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
551#else
552 PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
553 PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
554 PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
555#endif
556
557 if (PyErr_Occurred()) {
558 Py_DECREF(v);
559 return NULL;
560 }
561
562 return v;
563}
564
565
Barry Warsaw53699e91996-12-10 23:23:01 +0000566static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000567posix_do_stat(PyObject *self, PyObject *args, char *format,
568 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000569{
Fred Drake699f3522000-06-29 21:12:41 +0000570 STRUCT_STAT st;
Mark Hammondef8b6542001-05-13 08:04:26 +0000571 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000572 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000573
574#ifdef MS_WIN32
575 int pathlen;
576 char pathcopy[MAX_PATH];
577#endif /* MS_WIN32 */
578
Mark Hammondef8b6542001-05-13 08:04:26 +0000579 if (!PyArg_ParseTuple(args, format,
580 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000581 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000582
583#ifdef MS_WIN32
584 pathlen = strlen(path);
585 /* the library call can blow up if the file name is too long! */
586 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000587 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000588 errno = ENAMETOOLONG;
589 return posix_error();
590 }
591
592 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000593 /* exception for specific or current drive root */
594 if (!((pathlen == 1) ||
595 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000596 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000597 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000598 {
599 strncpy(pathcopy, path, pathlen);
600 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
601 path = pathcopy;
602 }
603 }
604#endif /* MS_WIN32 */
605
Barry Warsaw53699e91996-12-10 23:23:01 +0000606 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000607 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000608 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000609 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000610 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000611
Mark Hammondef8b6542001-05-13 08:04:26 +0000612 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000613 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614}
615
616
617/* POSIX methods */
618
Guido van Rossum94f6f721999-01-06 18:42:14 +0000619static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000620"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000621Test for access to a file.";
622
623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000624posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000625{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000626 char *path;
627 int mode;
628 int res;
629
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000630 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000631 return NULL;
632 Py_BEGIN_ALLOW_THREADS
633 res = access(path, mode);
634 Py_END_ALLOW_THREADS
635 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000636}
637
Guido van Rossumd371ff11999-01-25 16:12:23 +0000638#ifndef F_OK
639#define F_OK 0
640#endif
641#ifndef R_OK
642#define R_OK 4
643#endif
644#ifndef W_OK
645#define W_OK 2
646#endif
647#ifndef X_OK
648#define X_OK 1
649#endif
650
651#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000652static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000653"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000654Return the name of the terminal device connected to 'fd'.";
655
656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000657posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000658{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000659 int id;
660 char *ret;
661
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000662 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000663 return NULL;
664
Guido van Rossum94f6f721999-01-06 18:42:14 +0000665 ret = ttyname(id);
666 if (ret == NULL)
667 return(posix_error());
668 return(PyString_FromString(ret));
669}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000670#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000671
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000672#ifdef HAVE_CTERMID
673static char posix_ctermid__doc__[] =
674"ctermid() -> String\n\
675Return the name of the controlling terminal for this process.";
676
677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000678posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000679{
680 char *ret;
681 char buffer[L_ctermid];
682
683 if (!PyArg_ParseTuple(args, ":ctermid"))
684 return NULL;
685
Greg Wardb48bc172000-03-01 21:51:56 +0000686#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000687 ret = ctermid_r(buffer);
688#else
689 ret = ctermid(buffer);
690#endif
691 if (ret == NULL)
692 return(posix_error());
693 return(PyString_FromString(buffer));
694}
695#endif
696
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000697static char posix_chdir__doc__[] =
698"chdir(path) -> None\n\
699Change the current working directory to the specified path.";
700
Barry Warsaw53699e91996-12-10 23:23:01 +0000701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000702posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000703{
Mark Hammondef8b6542001-05-13 08:04:26 +0000704 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000705}
706
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000707
708static char posix_chmod__doc__[] =
709"chmod(path, mode) -> None\n\
710Change the access permissions of a file.";
711
Barry Warsaw53699e91996-12-10 23:23:01 +0000712static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000713posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000714{
Mark Hammondef8b6542001-05-13 08:04:26 +0000715 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000716 int i;
717 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000718 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
719 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000720 return NULL;
721 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000722 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000723 Py_END_ALLOW_THREADS
724 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000725 return posix_error_with_allocated_filename(path);
726 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000727 Py_INCREF(Py_None);
728 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000729}
730
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000731
Martin v. Löwis244edc82001-10-04 22:44:26 +0000732#ifdef HAVE_CHROOT
733static char posix_chroot__doc__[] =
734"chroot(path) -> None\n\
735Change root directory to path.";
736
737static PyObject *
738posix_chroot(PyObject *self, PyObject *args)
739{
740 return posix_1str(args, "et:chroot", chroot);
741}
742#endif
743
Guido van Rossum21142a01999-01-08 21:05:37 +0000744#ifdef HAVE_FSYNC
745static char posix_fsync__doc__[] =
746"fsync(fildes) -> None\n\
747force write of file with filedescriptor to disk.";
748
749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000750posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000751{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000752 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000753}
754#endif /* HAVE_FSYNC */
755
756#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000757
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000758#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000759extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
760#endif
761
Guido van Rossum21142a01999-01-08 21:05:37 +0000762static char posix_fdatasync__doc__[] =
763"fdatasync(fildes) -> None\n\
764force write of file with filedescriptor to disk.\n\
765 does not force update of metadata.";
766
767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000768posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000769{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000770 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000771}
772#endif /* HAVE_FDATASYNC */
773
774
Fredrik Lundh10723342000-07-10 16:38:09 +0000775#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000776static char posix_chown__doc__[] =
777"chown(path, uid, gid) -> None\n\
778Change the owner and group id of path to the numeric uid and gid.";
779
Barry Warsaw53699e91996-12-10 23:23:01 +0000780static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000781posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000782{
Mark Hammondef8b6542001-05-13 08:04:26 +0000783 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000784 int uid, gid;
785 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000786 if (!PyArg_ParseTuple(args, "etii:chown",
787 Py_FileSystemDefaultEncoding, &path,
788 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000789 return NULL;
790 Py_BEGIN_ALLOW_THREADS
791 res = chown(path, (uid_t) uid, (gid_t) gid);
792 Py_END_ALLOW_THREADS
793 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000794 return posix_error_with_allocated_filename(path);
795 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000796 Py_INCREF(Py_None);
797 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000798}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000799#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000800
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000801
Guido van Rossum36bc6801995-06-14 22:54:23 +0000802#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000803static char posix_getcwd__doc__[] =
804"getcwd() -> path\n\
805Return a string representing the current working directory.";
806
Barry Warsaw53699e91996-12-10 23:23:01 +0000807static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000808posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000809{
810 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000811 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000812 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000814 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000815 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000816 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000817 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000818 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000819 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000820}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000821#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000823
Guido van Rossumb6775db1994-08-01 11:34:53 +0000824#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000825static char posix_link__doc__[] =
826"link(src, dst) -> None\n\
827Create a hard link to a file.";
828
Barry Warsaw53699e91996-12-10 23:23:01 +0000829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000830posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000831{
Mark Hammondef8b6542001-05-13 08:04:26 +0000832 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000833}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000834#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000835
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000836
837static char posix_listdir__doc__[] =
838"listdir(path) -> list_of_strings\n\
839Return a list containing the names of the entries in the directory.\n\
840\n\
841 path: path of directory to list\n\
842\n\
843The list is in arbitrary order. It does not include the special\n\
844entries '.' and '..' even if they are present in the directory.";
845
Barry Warsaw53699e91996-12-10 23:23:01 +0000846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000847posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000848{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000849 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000850 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000851#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000852
Barry Warsaw53699e91996-12-10 23:23:01 +0000853 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000854 HANDLE hFindFile;
855 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000856 /* MAX_PATH characters could mean a bigger encoded string */
857 char namebuf[MAX_PATH*2+5];
858 char *bufptr = namebuf;
859 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000860 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000861
Mark Hammondef8b6542001-05-13 08:04:26 +0000862 if (!PyArg_ParseTuple(args, "et#:listdir",
863 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000864 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000865 ch = namebuf[len-1];
866 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000867 namebuf[len++] = '/';
868 strcpy(namebuf + len, "*.*");
869
Barry Warsaw53699e91996-12-10 23:23:01 +0000870 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000871 return NULL;
872
873 hFindFile = FindFirstFile(namebuf, &FileData);
874 if (hFindFile == INVALID_HANDLE_VALUE) {
875 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000876 if (errno == ERROR_FILE_NOT_FOUND)
877 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000878 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000879 }
880 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000881 if (FileData.cFileName[0] == '.' &&
882 (FileData.cFileName[1] == '\0' ||
883 FileData.cFileName[1] == '.' &&
884 FileData.cFileName[2] == '\0'))
885 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000886 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000887 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000888 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000889 d = NULL;
890 break;
891 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000892 if (PyList_Append(d, v) != 0) {
893 Py_DECREF(v);
894 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000895 d = NULL;
896 break;
897 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000898 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000899 } while (FindNextFile(hFindFile, &FileData) == TRUE);
900
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000901 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +0000902 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000903
904 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000905
Tim Peters0bb44a42000-09-15 07:44:49 +0000906#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000907
908#ifndef MAX_PATH
909#define MAX_PATH 250
910#endif
911 char *name, *pt;
912 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +0000913 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000914 char namebuf[MAX_PATH+5];
915 struct _find_t ep;
916
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000917 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000918 return NULL;
919 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000920 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000921 return NULL;
922 }
923 strcpy(namebuf, name);
924 for (pt = namebuf; *pt; pt++)
925 if (*pt == '/')
926 *pt = '\\';
927 if (namebuf[len-1] != '\\')
928 namebuf[len++] = '\\';
929 strcpy(namebuf + len, "*.*");
930
Barry Warsaw53699e91996-12-10 23:23:01 +0000931 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000932 return NULL;
933
934 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +0000935 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
936 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000937 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +0000938 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000939 }
940 do {
941 if (ep.name[0] == '.' &&
942 (ep.name[1] == '\0' ||
943 ep.name[1] == '.' &&
944 ep.name[2] == '\0'))
945 continue;
946 strcpy(namebuf, ep.name);
947 for (pt = namebuf; *pt; pt++)
948 if (isupper(*pt))
949 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +0000950 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000951 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000952 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000953 d = NULL;
954 break;
955 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000956 if (PyList_Append(d, v) != 0) {
957 Py_DECREF(v);
958 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000959 d = NULL;
960 break;
961 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000962 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000963 } while (_dos_findnext(&ep) == 0);
964
965 return d;
966
Tim Peters0bb44a42000-09-15 07:44:49 +0000967#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000968
969#ifndef MAX_PATH
970#define MAX_PATH CCHMAXPATH
971#endif
972 char *name, *pt;
973 int len;
974 PyObject *d, *v;
975 char namebuf[MAX_PATH+5];
976 HDIR hdir = 1;
977 ULONG srchcnt = 1;
978 FILEFINDBUF3 ep;
979 APIRET rc;
980
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000981 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000982 return NULL;
983 if (len >= MAX_PATH) {
984 PyErr_SetString(PyExc_ValueError, "path too long");
985 return NULL;
986 }
987 strcpy(namebuf, name);
988 for (pt = namebuf; *pt; pt++)
989 if (*pt == '/')
990 *pt = '\\';
991 if (namebuf[len-1] != '\\')
992 namebuf[len++] = '\\';
993 strcpy(namebuf + len, "*.*");
994
995 if ((d = PyList_New(0)) == NULL)
996 return NULL;
997
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000998 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
999 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001000 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001001 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1002 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1003 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001004
1005 if (rc != NO_ERROR) {
1006 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001007 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001008 }
1009
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001010 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001011 do {
1012 if (ep.achName[0] == '.'
1013 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001014 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001015
1016 strcpy(namebuf, ep.achName);
1017
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001018 /* Leave Case of Name Alone -- In Native Form */
1019 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001020
1021 v = PyString_FromString(namebuf);
1022 if (v == NULL) {
1023 Py_DECREF(d);
1024 d = NULL;
1025 break;
1026 }
1027 if (PyList_Append(d, v) != 0) {
1028 Py_DECREF(v);
1029 Py_DECREF(d);
1030 d = NULL;
1031 break;
1032 }
1033 Py_DECREF(v);
1034 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1035 }
1036
1037 return d;
1038#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001039
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001040 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001041 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001042 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001043 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001044 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001045 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001046 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001047 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001048 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001049 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001050 closedir(dirp);
1051 return NULL;
1052 }
1053 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001054 if (ep->d_name[0] == '.' &&
1055 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001056 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001057 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001058 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001059 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001060 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001061 d = NULL;
1062 break;
1063 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001064 if (PyList_Append(d, v) != 0) {
1065 Py_DECREF(v);
1066 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001067 d = NULL;
1068 break;
1069 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001070 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001071 }
1072 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001073
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001074 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001075
Tim Peters0bb44a42000-09-15 07:44:49 +00001076#endif /* which OS */
1077} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001078
Mark Hammondef8b6542001-05-13 08:04:26 +00001079#ifdef MS_WIN32
1080/* A helper function for abspath on win32 */
1081static PyObject *
1082posix__getfullpathname(PyObject *self, PyObject *args)
1083{
1084 /* assume encoded strings wont more than double no of chars */
1085 char inbuf[MAX_PATH*2];
1086 char *inbufp = inbuf;
1087 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1088 char outbuf[MAX_PATH*2];
1089 char *temp;
1090 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1091 Py_FileSystemDefaultEncoding, &inbufp,
1092 &insize))
1093 return NULL;
1094 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1095 outbuf, &temp))
1096 return win32_error("GetFullPathName", inbuf);
1097 return PyString_FromString(outbuf);
1098} /* end of posix__getfullpathname */
1099#endif /* MS_WIN32 */
1100
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001101static char posix_mkdir__doc__[] =
1102"mkdir(path [, mode=0777]) -> None\n\
1103Create a directory.";
1104
Barry Warsaw53699e91996-12-10 23:23:01 +00001105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001106posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001107{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001108 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001109 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001110 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001111 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1112 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001113 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001114 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001115#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001116 res = mkdir(path);
1117#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001118 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001119#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001120 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001121 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001122 return posix_error_with_allocated_filename(path);
1123 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001124 Py_INCREF(Py_None);
1125 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001126}
1127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001128
Guido van Rossumb6775db1994-08-01 11:34:53 +00001129#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001130#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1131#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1132#include <sys/resource.h>
1133#endif
1134#endif
1135
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001136static char posix_nice__doc__[] =
1137"nice(inc) -> new_priority\n\
1138Decrease the priority of process and return new priority.";
1139
Barry Warsaw53699e91996-12-10 23:23:01 +00001140static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001141posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001142{
1143 int increment, value;
1144
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001145 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001146 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001147
1148 /* There are two flavours of 'nice': one that returns the new
1149 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001150 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1151 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001152
1153 If we are of the nice family that returns the new priority, we
1154 need to clear errno before the call, and check if errno is filled
1155 before calling posix_error() on a returnvalue of -1, because the
1156 -1 may be the actual new priority! */
1157
1158 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001159 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001160#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001161 if (value == 0)
1162 value = getpriority(PRIO_PROCESS, 0);
1163#endif
1164 if (value == -1 && errno != 0)
1165 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001166 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001167 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001168}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001169#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001170
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001171
1172static char posix_rename__doc__[] =
1173"rename(old, new) -> None\n\
1174Rename a file or directory.";
1175
Barry Warsaw53699e91996-12-10 23:23:01 +00001176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001177posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178{
Mark Hammondef8b6542001-05-13 08:04:26 +00001179 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001180}
1181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001182
1183static char posix_rmdir__doc__[] =
1184"rmdir(path) -> None\n\
1185Remove a directory.";
1186
Barry Warsaw53699e91996-12-10 23:23:01 +00001187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001188posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189{
Mark Hammondef8b6542001-05-13 08:04:26 +00001190 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191}
1192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001193
1194static char posix_stat__doc__[] =
1195"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1196Perform a stat system call on the given path.";
1197
Barry Warsaw53699e91996-12-10 23:23:01 +00001198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001199posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001200{
Mark Hammondef8b6542001-05-13 08:04:26 +00001201 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001202}
1203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001204
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001205#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001206static char posix_system__doc__[] =
1207"system(command) -> exit_status\n\
1208Execute the command (a string) in a subshell.";
1209
Barry Warsaw53699e91996-12-10 23:23:01 +00001210static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001211posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001212{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001213 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001214 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001215 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001216 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001217 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001218 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001219 Py_END_ALLOW_THREADS
1220 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001222#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001224
1225static char posix_umask__doc__[] =
1226"umask(new_mask) -> old_mask\n\
1227Set the current numeric umask and return the previous umask.";
1228
Barry Warsaw53699e91996-12-10 23:23:01 +00001229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001230posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001231{
1232 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001233 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001234 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001235 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001236 if (i < 0)
1237 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001238 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001239}
1240
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001241
1242static char posix_unlink__doc__[] =
1243"unlink(path) -> None\n\
1244Remove a file (same as remove(path)).";
1245
1246static char posix_remove__doc__[] =
1247"remove(path) -> None\n\
1248Remove a file (same as unlink(path)).";
1249
Barry Warsaw53699e91996-12-10 23:23:01 +00001250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001251posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252{
Mark Hammondef8b6542001-05-13 08:04:26 +00001253 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254}
1255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001256
Guido van Rossumb6775db1994-08-01 11:34:53 +00001257#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001258static char posix_uname__doc__[] =
1259"uname() -> (sysname, nodename, release, version, machine)\n\
1260Return a tuple identifying the current operating system.";
1261
Barry Warsaw53699e91996-12-10 23:23:01 +00001262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001263posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001264{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001265 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001266 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001267 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001268 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001269 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001270 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001271 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001272 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001273 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001274 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001275 u.sysname,
1276 u.nodename,
1277 u.release,
1278 u.version,
1279 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001280}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001281#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001282
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001283
1284static char posix_utime__doc__[] =
1285"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001286utime(path, None) -> None\n\
1287Set the access and modified time of the file to the given values. If the\n\
1288second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001289
Barry Warsaw53699e91996-12-10 23:23:01 +00001290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001291posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001292{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001293 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001294 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001295 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001296 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001297
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001298/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001299#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001300 struct utimbuf buf;
1301#define ATIME buf.actime
1302#define MTIME buf.modtime
1303#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001304#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001305 time_t buf[2];
1306#define ATIME buf[0]
1307#define MTIME buf[1]
1308#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001309#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001310
Barry Warsaw3cef8562000-05-01 16:17:24 +00001311 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001313 if (arg == Py_None) {
1314 /* optional time values not given */
1315 Py_BEGIN_ALLOW_THREADS
1316 res = utime(path, NULL);
1317 Py_END_ALLOW_THREADS
1318 }
1319 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1320 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001321 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001322 return NULL;
1323 }
1324 else {
1325 ATIME = atime;
1326 MTIME = mtime;
1327 Py_BEGIN_ALLOW_THREADS
1328 res = utime(path, UTIME_ARG);
1329 Py_END_ALLOW_THREADS
1330 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001331 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001332 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001333 Py_INCREF(Py_None);
1334 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001335#undef UTIME_ARG
1336#undef ATIME
1337#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001338}
1339
Guido van Rossum85e3b011991-06-03 12:42:10 +00001340
Guido van Rossum3b066191991-06-04 19:40:25 +00001341/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001342
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001343static char posix__exit__doc__[] =
1344"_exit(status)\n\
1345Exit to the system with specified status, without normal exit processing.";
1346
Barry Warsaw53699e91996-12-10 23:23:01 +00001347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001348posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001349{
1350 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001351 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001352 return NULL;
1353 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001354 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001355}
1356
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001357
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001358#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001359static char posix_execv__doc__[] =
1360"execv(path, args)\n\
1361Execute an executable path with arguments, replacing current process.\n\
1362\n\
1363 path: path of executable file\n\
1364 args: tuple or list of strings";
1365
Barry Warsaw53699e91996-12-10 23:23:01 +00001366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001367posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001368{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001369 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001370 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001371 char **argvlist;
1372 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001373 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001374
Guido van Rossum89b33251993-10-22 14:26:06 +00001375 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001376 argv is a list or tuple of strings. */
1377
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001378 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001379 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001380 if (PyList_Check(argv)) {
1381 argc = PyList_Size(argv);
1382 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001383 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001384 else if (PyTuple_Check(argv)) {
1385 argc = PyTuple_Size(argv);
1386 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001387 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001388 else {
Fred Drake661ea262000-10-24 19:57:45 +00001389 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001390 return NULL;
1391 }
1392
1393 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001394 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001395 return NULL;
1396 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001397
Barry Warsaw53699e91996-12-10 23:23:01 +00001398 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001399 if (argvlist == NULL)
1400 return NULL;
1401 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001402 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1403 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001404 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001405 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001406 return NULL;
1407
Guido van Rossum85e3b011991-06-03 12:42:10 +00001408 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001409 }
1410 argvlist[argc] = NULL;
1411
Guido van Rossumb6775db1994-08-01 11:34:53 +00001412#ifdef BAD_EXEC_PROTOTYPES
1413 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001414#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001415 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001416#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001417
Guido van Rossum85e3b011991-06-03 12:42:10 +00001418 /* If we get here it's definitely an error */
1419
Barry Warsaw53699e91996-12-10 23:23:01 +00001420 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001421 return posix_error();
1422}
1423
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001424
1425static char posix_execve__doc__[] =
1426"execve(path, args, env)\n\
1427Execute a path with arguments and environment, replacing current process.\n\
1428\n\
1429 path: path of executable file\n\
1430 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001431 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001432
Barry Warsaw53699e91996-12-10 23:23:01 +00001433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001434posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001435{
1436 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001437 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001438 char **argvlist;
1439 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001440 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001441 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001442 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001443
1444 /* execve has three arguments: (path, argv, env), where
1445 argv is a list or tuple of strings and env is a dictionary
1446 like posix.environ. */
1447
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001448 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001449 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001450 if (PyList_Check(argv)) {
1451 argc = PyList_Size(argv);
1452 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001453 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001454 else if (PyTuple_Check(argv)) {
1455 argc = PyTuple_Size(argv);
1456 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001457 }
1458 else {
Fred Drake661ea262000-10-24 19:57:45 +00001459 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001460 return NULL;
1461 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001462 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001463 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001464 return NULL;
1465 }
1466
Guido van Rossum50422b42000-04-26 20:34:28 +00001467 if (argc == 0) {
1468 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001469 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001470 return NULL;
1471 }
1472
Barry Warsaw53699e91996-12-10 23:23:01 +00001473 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001474 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001475 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001476 return NULL;
1477 }
1478 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001479 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001480 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001481 &argvlist[i]))
1482 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001483 goto fail_1;
1484 }
1485 }
1486 argvlist[argc] = NULL;
1487
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001488 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001489 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001490 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001491 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001492 goto fail_1;
1493 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001494 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001495 keys = PyMapping_Keys(env);
1496 vals = PyMapping_Values(env);
1497 if (!keys || !vals)
1498 goto fail_2;
1499
1500 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001501 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001502
1503 key = PyList_GetItem(keys, pos);
1504 val = PyList_GetItem(vals, pos);
1505 if (!key || !val)
1506 goto fail_2;
1507
Fred Drake661ea262000-10-24 19:57:45 +00001508 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1509 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001510 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001511 goto fail_2;
1512 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001513
1514#if defined(PYOS_OS2)
1515 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1516 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1517#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001518 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001519 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001520 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001521 goto fail_2;
1522 }
1523 sprintf(p, "%s=%s", k, v);
1524 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001525#if defined(PYOS_OS2)
1526 }
1527#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001528 }
1529 envlist[envc] = 0;
1530
Guido van Rossumb6775db1994-08-01 11:34:53 +00001531
1532#ifdef BAD_EXEC_PROTOTYPES
1533 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001534#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001535 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001536#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001537
1538 /* If we get here it's definitely an error */
1539
1540 (void) posix_error();
1541
1542 fail_2:
1543 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001544 PyMem_DEL(envlist[envc]);
1545 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001546 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001547 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001548 Py_XDECREF(vals);
1549 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001550 return NULL;
1551}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001552#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001553
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001554
Guido van Rossuma1065681999-01-25 23:20:23 +00001555#ifdef HAVE_SPAWNV
1556static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001557"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001558Execute an executable path with arguments, replacing current process.\n\
1559\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001560 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001561 path: path of executable file\n\
1562 args: tuple or list of strings";
1563
1564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001565posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001566{
1567 char *path;
1568 PyObject *argv;
1569 char **argvlist;
1570 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001571 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001572 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001573
1574 /* spawnv has three arguments: (mode, path, argv), where
1575 argv is a list or tuple of strings. */
1576
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001577 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001578 return NULL;
1579 if (PyList_Check(argv)) {
1580 argc = PyList_Size(argv);
1581 getitem = PyList_GetItem;
1582 }
1583 else if (PyTuple_Check(argv)) {
1584 argc = PyTuple_Size(argv);
1585 getitem = PyTuple_GetItem;
1586 }
1587 else {
Fred Drake661ea262000-10-24 19:57:45 +00001588 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001589 return NULL;
1590 }
1591
1592 argvlist = PyMem_NEW(char *, argc+1);
1593 if (argvlist == NULL)
1594 return NULL;
1595 for (i = 0; i < argc; i++) {
1596 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1597 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001598 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001599 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001600 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001601 }
1602 }
1603 argvlist[argc] = NULL;
1604
Guido van Rossum246bc171999-02-01 23:54:31 +00001605 if (mode == _OLD_P_OVERLAY)
1606 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001607 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001608
1609 PyMem_DEL(argvlist);
1610
Fred Drake699f3522000-06-29 21:12:41 +00001611 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001612 return posix_error();
1613 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001614#if SIZEOF_LONG == SIZEOF_VOID_P
1615 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001616#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001617 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001618#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001619}
1620
1621
1622static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001623"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001624Execute a path with arguments and environment, replacing current process.\n\
1625\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001626 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001627 path: path of executable file\n\
1628 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001629 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001630
1631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001632posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001633{
1634 char *path;
1635 PyObject *argv, *env;
1636 char **argvlist;
1637 char **envlist;
1638 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1639 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001640 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001641 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001642
1643 /* spawnve has four arguments: (mode, path, argv, env), where
1644 argv is a list or tuple of strings and env is a dictionary
1645 like posix.environ. */
1646
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001647 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001648 return NULL;
1649 if (PyList_Check(argv)) {
1650 argc = PyList_Size(argv);
1651 getitem = PyList_GetItem;
1652 }
1653 else if (PyTuple_Check(argv)) {
1654 argc = PyTuple_Size(argv);
1655 getitem = PyTuple_GetItem;
1656 }
1657 else {
Fred Drake661ea262000-10-24 19:57:45 +00001658 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001659 return NULL;
1660 }
1661 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001662 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001663 return NULL;
1664 }
1665
1666 argvlist = PyMem_NEW(char *, argc+1);
1667 if (argvlist == NULL) {
1668 PyErr_NoMemory();
1669 return NULL;
1670 }
1671 for (i = 0; i < argc; i++) {
1672 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001673 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001674 &argvlist[i]))
1675 {
1676 goto fail_1;
1677 }
1678 }
1679 argvlist[argc] = NULL;
1680
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001681 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001682 envlist = PyMem_NEW(char *, i + 1);
1683 if (envlist == NULL) {
1684 PyErr_NoMemory();
1685 goto fail_1;
1686 }
1687 envc = 0;
1688 keys = PyMapping_Keys(env);
1689 vals = PyMapping_Values(env);
1690 if (!keys || !vals)
1691 goto fail_2;
1692
1693 for (pos = 0; pos < i; pos++) {
1694 char *p, *k, *v;
1695
1696 key = PyList_GetItem(keys, pos);
1697 val = PyList_GetItem(vals, pos);
1698 if (!key || !val)
1699 goto fail_2;
1700
Fred Drake661ea262000-10-24 19:57:45 +00001701 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1702 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001703 {
1704 goto fail_2;
1705 }
1706 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1707 if (p == NULL) {
1708 PyErr_NoMemory();
1709 goto fail_2;
1710 }
1711 sprintf(p, "%s=%s", k, v);
1712 envlist[envc++] = p;
1713 }
1714 envlist[envc] = 0;
1715
Guido van Rossum246bc171999-02-01 23:54:31 +00001716 if (mode == _OLD_P_OVERLAY)
1717 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001718 spawnval = _spawnve(mode, path, argvlist, envlist);
1719 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001720 (void) posix_error();
1721 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001722#if SIZEOF_LONG == SIZEOF_VOID_P
1723 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001724#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001725 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001726#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001727
1728 fail_2:
1729 while (--envc >= 0)
1730 PyMem_DEL(envlist[envc]);
1731 PyMem_DEL(envlist);
1732 fail_1:
1733 PyMem_DEL(argvlist);
1734 Py_XDECREF(vals);
1735 Py_XDECREF(keys);
1736 return res;
1737}
1738#endif /* HAVE_SPAWNV */
1739
1740
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001741#ifdef HAVE_FORK1
1742static char posix_fork1__doc__[] =
1743"fork1() -> pid\n\
1744Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1745\n\
1746Return 0 to child process and PID of child to parent process.";
1747
1748static PyObject *
1749posix_fork1(self, args)
1750 PyObject *self;
1751 PyObject *args;
1752{
1753 int pid;
1754 if (!PyArg_ParseTuple(args, ":fork1"))
1755 return NULL;
1756 pid = fork1();
1757 if (pid == -1)
1758 return posix_error();
1759 PyOS_AfterFork();
1760 return PyInt_FromLong((long)pid);
1761}
1762#endif
1763
1764
Guido van Rossumad0ee831995-03-01 10:34:45 +00001765#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001766static char posix_fork__doc__[] =
1767"fork() -> pid\n\
1768Fork a child process.\n\
1769\n\
1770Return 0 to child process and PID of child to parent process.";
1771
Barry Warsaw53699e91996-12-10 23:23:01 +00001772static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001773posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001774{
1775 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001776 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001777 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001778 pid = fork();
1779 if (pid == -1)
1780 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001781 if (pid == 0)
1782 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001783 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001784}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001785#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001786
Fred Drake8cef4cf2000-06-28 16:40:38 +00001787#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1788#ifdef HAVE_PTY_H
1789#include <pty.h>
1790#else
1791#ifdef HAVE_LIBUTIL_H
1792#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001793#endif /* HAVE_LIBUTIL_H */
1794#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001795#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001796
Thomas Wouters70c21a12000-07-14 14:28:33 +00001797#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001798static char posix_openpty__doc__[] =
1799"openpty() -> (master_fd, slave_fd)\n\
1800Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1801
1802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001803posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001804{
1805 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001806#ifndef HAVE_OPENPTY
1807 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001808#endif
1809
Fred Drake8cef4cf2000-06-28 16:40:38 +00001810 if (!PyArg_ParseTuple(args, ":openpty"))
1811 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001812
1813#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001814 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1815 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001816#else
1817 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1818 if (slave_name == NULL)
1819 return posix_error();
1820
1821 slave_fd = open(slave_name, O_RDWR);
1822 if (slave_fd < 0)
1823 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001824#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001825
Fred Drake8cef4cf2000-06-28 16:40:38 +00001826 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001827
Fred Drake8cef4cf2000-06-28 16:40:38 +00001828}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001829#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001830
1831#ifdef HAVE_FORKPTY
1832static char posix_forkpty__doc__[] =
1833"forkpty() -> (pid, master_fd)\n\
1834Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1835Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1836To both, return fd of newly opened pseudo-terminal.\n";
1837
1838static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001839posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001840{
1841 int master_fd, pid;
1842
1843 if (!PyArg_ParseTuple(args, ":forkpty"))
1844 return NULL;
1845 pid = forkpty(&master_fd, NULL, NULL, NULL);
1846 if (pid == -1)
1847 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001848 if (pid == 0)
1849 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001850 return Py_BuildValue("(ii)", pid, master_fd);
1851}
1852#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001853
Guido van Rossumad0ee831995-03-01 10:34:45 +00001854#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001855static char posix_getegid__doc__[] =
1856"getegid() -> egid\n\
1857Return the current process's effective group id.";
1858
Barry Warsaw53699e91996-12-10 23:23:01 +00001859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001860posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001861{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001862 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001863 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001864 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001865}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001866#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001868
Guido van Rossumad0ee831995-03-01 10:34:45 +00001869#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001870static char posix_geteuid__doc__[] =
1871"geteuid() -> euid\n\
1872Return the current process's effective user id.";
1873
Barry Warsaw53699e91996-12-10 23:23:01 +00001874static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001875posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001876{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001877 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001878 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001879 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001880}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001881#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001882
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001883
Guido van Rossumad0ee831995-03-01 10:34:45 +00001884#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001885static char posix_getgid__doc__[] =
1886"getgid() -> gid\n\
1887Return the current process's group id.";
1888
Barry Warsaw53699e91996-12-10 23:23:01 +00001889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001890posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001891{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001892 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001893 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001894 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001895}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001896#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001898
1899static char posix_getpid__doc__[] =
1900"getpid() -> pid\n\
1901Return the current process id";
1902
Barry Warsaw53699e91996-12-10 23:23:01 +00001903static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001904posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001905{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001906 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001907 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001908 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00001909}
1910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001911
Fred Drakec9680921999-12-13 16:37:25 +00001912#ifdef HAVE_GETGROUPS
1913static char posix_getgroups__doc__[] = "\
1914getgroups() -> list of group IDs\n\
1915Return list of supplemental group IDs for the process.";
1916
1917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001918posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00001919{
1920 PyObject *result = NULL;
1921
1922 if (PyArg_ParseTuple(args, ":getgroups")) {
1923#ifdef NGROUPS_MAX
1924#define MAX_GROUPS NGROUPS_MAX
1925#else
1926 /* defined to be 16 on Solaris7, so this should be a small number */
1927#define MAX_GROUPS 64
1928#endif
1929 gid_t grouplist[MAX_GROUPS];
1930 int n;
1931
1932 n = getgroups(MAX_GROUPS, grouplist);
1933 if (n < 0)
1934 posix_error();
1935 else {
1936 result = PyList_New(n);
1937 if (result != NULL) {
1938 PyObject *o;
1939 int i;
1940 for (i = 0; i < n; ++i) {
1941 o = PyInt_FromLong((long)grouplist[i]);
1942 if (o == NULL) {
1943 Py_DECREF(result);
1944 result = NULL;
1945 break;
1946 }
1947 PyList_SET_ITEM(result, i, o);
1948 }
1949 }
1950 }
1951 }
1952 return result;
1953}
1954#endif
1955
Guido van Rossumb6775db1994-08-01 11:34:53 +00001956#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001957static char posix_getpgrp__doc__[] =
1958"getpgrp() -> pgrp\n\
1959Return the current process group id.";
1960
Barry Warsaw53699e91996-12-10 23:23:01 +00001961static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001962posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00001963{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001964 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00001965 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001966#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00001967 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001968#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00001969 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001970#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00001971}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001972#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00001973
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001974
Guido van Rossumb6775db1994-08-01 11:34:53 +00001975#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001976static char posix_setpgrp__doc__[] =
1977"setpgrp() -> None\n\
1978Make this process a session leader.";
1979
Barry Warsaw53699e91996-12-10 23:23:01 +00001980static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001981posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00001982{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001983 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00001984 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00001985#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00001986 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001987#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001988 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00001989#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00001990 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001991 Py_INCREF(Py_None);
1992 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00001993}
1994
Guido van Rossumb6775db1994-08-01 11:34:53 +00001995#endif /* HAVE_SETPGRP */
1996
Guido van Rossumad0ee831995-03-01 10:34:45 +00001997#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001998static char posix_getppid__doc__[] =
1999"getppid() -> ppid\n\
2000Return the parent's process id.";
2001
Barry Warsaw53699e91996-12-10 23:23:01 +00002002static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002003posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002004{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002005 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002006 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002007 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002008}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002009#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002011
Fred Drake12c6e2d1999-12-14 21:25:03 +00002012#ifdef HAVE_GETLOGIN
2013static char posix_getlogin__doc__[] = "\
2014getlogin() -> string\n\
2015Return the actual login name.";
2016
2017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002018posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002019{
2020 PyObject *result = NULL;
2021
2022 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002023 char *name;
2024 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002025
Fred Drakea30680b2000-12-06 21:24:28 +00002026 errno = 0;
2027 name = getlogin();
2028 if (name == NULL) {
2029 if (errno)
2030 posix_error();
2031 else
2032 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002033 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002034 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002035 else
2036 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002037 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002038 }
2039 return result;
2040}
2041#endif
2042
Guido van Rossumad0ee831995-03-01 10:34:45 +00002043#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002044static char posix_getuid__doc__[] =
2045"getuid() -> uid\n\
2046Return the current process's user id.";
2047
Barry Warsaw53699e91996-12-10 23:23:01 +00002048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002049posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002050{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002051 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002052 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002053 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002054}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002055#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002057
Guido van Rossumad0ee831995-03-01 10:34:45 +00002058#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059static char posix_kill__doc__[] =
2060"kill(pid, sig) -> None\n\
2061Kill a process with a signal.";
2062
Barry Warsaw53699e91996-12-10 23:23:01 +00002063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002064posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002065{
2066 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002067 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002068 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002069#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002070 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2071 APIRET rc;
2072 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002073 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002074
2075 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2076 APIRET rc;
2077 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002078 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002079
2080 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002081 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002082#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002083 if (kill(pid, sig) == -1)
2084 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002085#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 Py_INCREF(Py_None);
2087 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002088}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002089#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002090
Guido van Rossumc0125471996-06-28 18:55:32 +00002091#ifdef HAVE_PLOCK
2092
2093#ifdef HAVE_SYS_LOCK_H
2094#include <sys/lock.h>
2095#endif
2096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002097static char posix_plock__doc__[] =
2098"plock(op) -> None\n\
2099Lock program segments into memory.";
2100
Barry Warsaw53699e91996-12-10 23:23:01 +00002101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002102posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002103{
2104 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002105 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002106 return NULL;
2107 if (plock(op) == -1)
2108 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002109 Py_INCREF(Py_None);
2110 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002111}
2112#endif
2113
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002114
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002115#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002116static char posix_popen__doc__[] =
2117"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2118Open a pipe to/from a command returning a file object.";
2119
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002120#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002121static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002122async_system(const char *command)
2123{
2124 char *p, errormsg[256], args[1024];
2125 RESULTCODES rcodes;
2126 APIRET rc;
2127 char *shell = getenv("COMSPEC");
2128 if (!shell)
2129 shell = "cmd";
2130
2131 strcpy(args, shell);
2132 p = &args[ strlen(args)+1 ];
2133 strcpy(p, "/c ");
2134 strcat(p, command);
2135 p += strlen(p) + 1;
2136 *p = '\0';
2137
2138 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002139 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002140 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002141 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002142 &rcodes, shell);
2143 return rc;
2144}
2145
Guido van Rossumd48f2521997-12-05 22:19:34 +00002146static FILE *
2147popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002148{
2149 HFILE rhan, whan;
2150 FILE *retfd = NULL;
2151 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2152
Guido van Rossumd48f2521997-12-05 22:19:34 +00002153 if (rc != NO_ERROR) {
2154 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002155 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002156 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002157
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002158 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2159 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002160
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002161 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2162 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002163
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002164 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2165 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002166
2167 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002168 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002169 }
2170
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002171 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2172 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002173
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002174 close(oldfd); /* And Close Saved STDOUT Handle */
2175 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002176
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002177 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2178 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002179
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002180 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2181 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002182
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002183 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2184 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002185
2186 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002187 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002188 }
2189
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002190 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2191 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002192
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002193 close(oldfd); /* And Close Saved STDIN Handle */
2194 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002195
Guido van Rossumd48f2521997-12-05 22:19:34 +00002196 } else {
2197 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002198 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002199 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002200}
2201
2202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002203posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002204{
2205 char *name;
2206 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002207 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002208 FILE *fp;
2209 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002210 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002211 return NULL;
2212 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002213 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002214 Py_END_ALLOW_THREADS
2215 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002216 return os2_error(err);
2217
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002218 f = PyFile_FromFile(fp, name, mode, fclose);
2219 if (f != NULL)
2220 PyFile_SetBufSize(f, bufsize);
2221 return f;
2222}
2223
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002224#elif defined(MS_WIN32)
2225
2226/*
2227 * Portable 'popen' replacement for Win32.
2228 *
2229 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2230 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002231 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002232 */
2233
2234#include <malloc.h>
2235#include <io.h>
2236#include <fcntl.h>
2237
2238/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2239#define POPEN_1 1
2240#define POPEN_2 2
2241#define POPEN_3 3
2242#define POPEN_4 4
2243
2244static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002245static int _PyPclose(FILE *file);
2246
2247/*
2248 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002249 * for use when retrieving the process exit code. See _PyPclose() below
2250 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002251 */
2252static PyObject *_PyPopenProcs = NULL;
2253
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002254
2255/* popen that works from a GUI.
2256 *
2257 * The result of this function is a pipe (file) connected to the
2258 * processes stdin or stdout, depending on the requested mode.
2259 */
2260
2261static PyObject *
2262posix_popen(PyObject *self, PyObject *args)
2263{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002264 PyObject *f, *s;
2265 int tm = 0;
2266
2267 char *cmdstring;
2268 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002269 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002270 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002271 return NULL;
2272
2273 s = PyTuple_New(0);
2274
2275 if (*mode == 'r')
2276 tm = _O_RDONLY;
2277 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002278 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002279 return NULL;
2280 } else
2281 tm = _O_WRONLY;
2282
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002283 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002284 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002285 return NULL;
2286 }
2287
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002288 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002289 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002290 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002291 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002292 else
2293 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2294
2295 return f;
2296}
2297
2298/* Variation on win32pipe.popen
2299 *
2300 * The result of this function is a pipe (file) connected to the
2301 * process's stdin, and a pipe connected to the process's stdout.
2302 */
2303
2304static PyObject *
2305win32_popen2(PyObject *self, PyObject *args)
2306{
2307 PyObject *f;
2308 int tm=0;
2309
2310 char *cmdstring;
2311 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002312 int bufsize = -1;
2313 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002314 return NULL;
2315
2316 if (*mode == 't')
2317 tm = _O_TEXT;
2318 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002319 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002320 return NULL;
2321 } else
2322 tm = _O_BINARY;
2323
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002324 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002325 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002326 return NULL;
2327 }
2328
2329 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002330
2331 return f;
2332}
2333
2334/*
2335 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002336 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002337 * The result of this function is 3 pipes - the process's stdin,
2338 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002339 */
2340
2341static PyObject *
2342win32_popen3(PyObject *self, PyObject *args)
2343{
2344 PyObject *f;
2345 int tm = 0;
2346
2347 char *cmdstring;
2348 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002349 int bufsize = -1;
2350 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002351 return NULL;
2352
2353 if (*mode == 't')
2354 tm = _O_TEXT;
2355 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002356 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002357 return NULL;
2358 } else
2359 tm = _O_BINARY;
2360
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002361 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002362 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002363 return NULL;
2364 }
2365
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002366 f = _PyPopen(cmdstring, tm, POPEN_3);
2367
2368 return f;
2369}
2370
2371/*
2372 * Variation on win32pipe.popen
2373 *
2374 * The result of this function is 2 pipes - the processes stdin,
2375 * and stdout+stderr combined as a single pipe.
2376 */
2377
2378static PyObject *
2379win32_popen4(PyObject *self, PyObject *args)
2380{
2381 PyObject *f;
2382 int tm = 0;
2383
2384 char *cmdstring;
2385 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002386 int bufsize = -1;
2387 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002388 return NULL;
2389
2390 if (*mode == 't')
2391 tm = _O_TEXT;
2392 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002393 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002394 return NULL;
2395 } else
2396 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002397
2398 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002399 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002400 return NULL;
2401 }
2402
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002403 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002404
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002405 return f;
2406}
2407
Mark Hammond08501372001-01-31 07:30:29 +00002408static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002409_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002410 HANDLE hStdin,
2411 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002412 HANDLE hStderr,
2413 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002414{
2415 PROCESS_INFORMATION piProcInfo;
2416 STARTUPINFO siStartInfo;
2417 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002418 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002419 int i;
2420 int x;
2421
2422 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002423 char *comshell;
2424
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002425 s1 = (char *)_alloca(i);
2426 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2427 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002428
2429 /* Explicitly check if we are using COMMAND.COM. If we are
2430 * then use the w9xpopen hack.
2431 */
2432 comshell = s1 + x;
2433 while (comshell >= s1 && *comshell != '\\')
2434 --comshell;
2435 ++comshell;
2436
2437 if (GetVersion() < 0x80000000 &&
2438 _stricmp(comshell, "command.com") != 0) {
2439 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002440 x = i + strlen(s3) + strlen(cmdstring) + 1;
2441 s2 = (char *)_alloca(x);
2442 ZeroMemory(s2, x);
2443 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2444 }
2445 else {
2446 /*
Tim Peters402d5982001-08-27 06:37:48 +00002447 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2448 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002449 */
Mark Hammond08501372001-01-31 07:30:29 +00002450 char modulepath[_MAX_PATH];
2451 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002452 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2453 for (i = x = 0; modulepath[i]; i++)
2454 if (modulepath[i] == '\\')
2455 x = i+1;
2456 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002457 /* Create the full-name to w9xpopen, so we can test it exists */
2458 strncat(modulepath,
2459 szConsoleSpawn,
2460 (sizeof(modulepath)/sizeof(modulepath[0]))
2461 -strlen(modulepath));
2462 if (stat(modulepath, &statinfo) != 0) {
2463 /* Eeek - file-not-found - possibly an embedding
2464 situation - see if we can locate it in sys.prefix
2465 */
2466 strncpy(modulepath,
2467 Py_GetExecPrefix(),
2468 sizeof(modulepath)/sizeof(modulepath[0]));
2469 if (modulepath[strlen(modulepath)-1] != '\\')
2470 strcat(modulepath, "\\");
2471 strncat(modulepath,
2472 szConsoleSpawn,
2473 (sizeof(modulepath)/sizeof(modulepath[0]))
2474 -strlen(modulepath));
2475 /* No where else to look - raise an easily identifiable
2476 error, rather than leaving Windows to report
2477 "file not found" - as the user is probably blissfully
2478 unaware this shim EXE is used, and it will confuse them.
2479 (well, it confused me for a while ;-)
2480 */
2481 if (stat(modulepath, &statinfo) != 0) {
2482 PyErr_Format(PyExc_RuntimeError,
2483 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002484 "for popen to work with your shell "
2485 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002486 szConsoleSpawn);
2487 return FALSE;
2488 }
2489 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002490 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2491 strlen(modulepath) +
2492 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002493
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002494 s2 = (char *)_alloca(x);
2495 ZeroMemory(s2, x);
2496 sprintf(
2497 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002498 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002499 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002500 s1,
2501 s3,
2502 cmdstring);
2503 }
2504 }
2505
2506 /* Could be an else here to try cmd.exe / command.com in the path
2507 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002508 else {
Tim Peters402d5982001-08-27 06:37:48 +00002509 PyErr_SetString(PyExc_RuntimeError,
2510 "Cannot locate a COMSPEC environment variable to "
2511 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002512 return FALSE;
2513 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002514
2515 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2516 siStartInfo.cb = sizeof(STARTUPINFO);
2517 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2518 siStartInfo.hStdInput = hStdin;
2519 siStartInfo.hStdOutput = hStdout;
2520 siStartInfo.hStdError = hStderr;
2521 siStartInfo.wShowWindow = SW_HIDE;
2522
2523 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002524 s2,
2525 NULL,
2526 NULL,
2527 TRUE,
2528 CREATE_NEW_CONSOLE,
2529 NULL,
2530 NULL,
2531 &siStartInfo,
2532 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002533 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002534 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002535
Mark Hammondb37a3732000-08-14 04:47:33 +00002536 /* Return process handle */
2537 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002538 return TRUE;
2539 }
Tim Peters402d5982001-08-27 06:37:48 +00002540 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002541 return FALSE;
2542}
2543
2544/* The following code is based off of KB: Q190351 */
2545
2546static PyObject *
2547_PyPopen(char *cmdstring, int mode, int n)
2548{
2549 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2550 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002551 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002552
2553 SECURITY_ATTRIBUTES saAttr;
2554 BOOL fSuccess;
2555 int fd1, fd2, fd3;
2556 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002557 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002558 PyObject *f;
2559
2560 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2561 saAttr.bInheritHandle = TRUE;
2562 saAttr.lpSecurityDescriptor = NULL;
2563
2564 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2565 return win32_error("CreatePipe", NULL);
2566
2567 /* Create new output read handle and the input write handle. Set
2568 * the inheritance properties to FALSE. Otherwise, the child inherits
2569 * the these handles; resulting in non-closeable handles to the pipes
2570 * being created. */
2571 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002572 GetCurrentProcess(), &hChildStdinWrDup, 0,
2573 FALSE,
2574 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002575 if (!fSuccess)
2576 return win32_error("DuplicateHandle", NULL);
2577
2578 /* Close the inheritable version of ChildStdin
2579 that we're using. */
2580 CloseHandle(hChildStdinWr);
2581
2582 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2583 return win32_error("CreatePipe", NULL);
2584
2585 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002586 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2587 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002588 if (!fSuccess)
2589 return win32_error("DuplicateHandle", NULL);
2590
2591 /* Close the inheritable version of ChildStdout
2592 that we're using. */
2593 CloseHandle(hChildStdoutRd);
2594
2595 if (n != POPEN_4) {
2596 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2597 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002598 fSuccess = DuplicateHandle(GetCurrentProcess(),
2599 hChildStderrRd,
2600 GetCurrentProcess(),
2601 &hChildStderrRdDup, 0,
2602 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002603 if (!fSuccess)
2604 return win32_error("DuplicateHandle", NULL);
2605 /* Close the inheritable version of ChildStdErr that we're using. */
2606 CloseHandle(hChildStderrRd);
2607 }
2608
2609 switch (n) {
2610 case POPEN_1:
2611 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2612 case _O_WRONLY | _O_TEXT:
2613 /* Case for writing to child Stdin in text mode. */
2614 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2615 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002616 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002617 PyFile_SetBufSize(f, 0);
2618 /* We don't care about these pipes anymore, so close them. */
2619 CloseHandle(hChildStdoutRdDup);
2620 CloseHandle(hChildStderrRdDup);
2621 break;
2622
2623 case _O_RDONLY | _O_TEXT:
2624 /* Case for reading from child Stdout in text mode. */
2625 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2626 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002627 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002628 PyFile_SetBufSize(f, 0);
2629 /* We don't care about these pipes anymore, so close them. */
2630 CloseHandle(hChildStdinWrDup);
2631 CloseHandle(hChildStderrRdDup);
2632 break;
2633
2634 case _O_RDONLY | _O_BINARY:
2635 /* Case for readinig from child Stdout in binary mode. */
2636 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2637 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002638 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002639 PyFile_SetBufSize(f, 0);
2640 /* We don't care about these pipes anymore, so close them. */
2641 CloseHandle(hChildStdinWrDup);
2642 CloseHandle(hChildStderrRdDup);
2643 break;
2644
2645 case _O_WRONLY | _O_BINARY:
2646 /* Case for writing to child Stdin in binary mode. */
2647 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2648 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002649 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002650 PyFile_SetBufSize(f, 0);
2651 /* We don't care about these pipes anymore, so close them. */
2652 CloseHandle(hChildStdoutRdDup);
2653 CloseHandle(hChildStderrRdDup);
2654 break;
2655 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002656 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002657 break;
2658
2659 case POPEN_2:
2660 case POPEN_4:
2661 {
2662 char *m1, *m2;
2663 PyObject *p1, *p2;
2664
2665 if (mode && _O_TEXT) {
2666 m1 = "r";
2667 m2 = "w";
2668 } else {
2669 m1 = "rb";
2670 m2 = "wb";
2671 }
2672
2673 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2674 f1 = _fdopen(fd1, m2);
2675 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2676 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002677 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002678 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002679 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002680 PyFile_SetBufSize(p2, 0);
2681
2682 if (n != 4)
2683 CloseHandle(hChildStderrRdDup);
2684
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002685 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002686 Py_XDECREF(p1);
2687 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002688 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002689 break;
2690 }
2691
2692 case POPEN_3:
2693 {
2694 char *m1, *m2;
2695 PyObject *p1, *p2, *p3;
2696
2697 if (mode && _O_TEXT) {
2698 m1 = "r";
2699 m2 = "w";
2700 } else {
2701 m1 = "rb";
2702 m2 = "wb";
2703 }
2704
2705 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2706 f1 = _fdopen(fd1, m2);
2707 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2708 f2 = _fdopen(fd2, m1);
2709 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2710 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002711 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002712 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2713 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002714 PyFile_SetBufSize(p1, 0);
2715 PyFile_SetBufSize(p2, 0);
2716 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002717 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002718 Py_XDECREF(p1);
2719 Py_XDECREF(p2);
2720 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002721 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002722 break;
2723 }
2724 }
2725
2726 if (n == POPEN_4) {
2727 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002728 hChildStdinRd,
2729 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002730 hChildStdoutWr,
2731 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002732 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002733 }
2734 else {
2735 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002736 hChildStdinRd,
2737 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002738 hChildStderrWr,
2739 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002740 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002741 }
2742
Mark Hammondb37a3732000-08-14 04:47:33 +00002743 /*
2744 * Insert the files we've created into the process dictionary
2745 * all referencing the list with the process handle and the
2746 * initial number of files (see description below in _PyPclose).
2747 * Since if _PyPclose later tried to wait on a process when all
2748 * handles weren't closed, it could create a deadlock with the
2749 * child, we spend some energy here to try to ensure that we
2750 * either insert all file handles into the dictionary or none
2751 * at all. It's a little clumsy with the various popen modes
2752 * and variable number of files involved.
2753 */
2754 if (!_PyPopenProcs) {
2755 _PyPopenProcs = PyDict_New();
2756 }
2757
2758 if (_PyPopenProcs) {
2759 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2760 int ins_rc[3];
2761
2762 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2763 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2764
2765 procObj = PyList_New(2);
2766 hProcessObj = PyLong_FromVoidPtr(hProcess);
2767 intObj = PyInt_FromLong(file_count);
2768
2769 if (procObj && hProcessObj && intObj) {
2770 PyList_SetItem(procObj,0,hProcessObj);
2771 PyList_SetItem(procObj,1,intObj);
2772
2773 fileObj[0] = PyLong_FromVoidPtr(f1);
2774 if (fileObj[0]) {
2775 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2776 fileObj[0],
2777 procObj);
2778 }
2779 if (file_count >= 2) {
2780 fileObj[1] = PyLong_FromVoidPtr(f2);
2781 if (fileObj[1]) {
2782 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2783 fileObj[1],
2784 procObj);
2785 }
2786 }
2787 if (file_count >= 3) {
2788 fileObj[2] = PyLong_FromVoidPtr(f3);
2789 if (fileObj[2]) {
2790 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2791 fileObj[2],
2792 procObj);
2793 }
2794 }
2795
2796 if (ins_rc[0] < 0 || !fileObj[0] ||
2797 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2798 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2799 /* Something failed - remove any dictionary
2800 * entries that did make it.
2801 */
2802 if (!ins_rc[0] && fileObj[0]) {
2803 PyDict_DelItem(_PyPopenProcs,
2804 fileObj[0]);
2805 }
2806 if (!ins_rc[1] && fileObj[1]) {
2807 PyDict_DelItem(_PyPopenProcs,
2808 fileObj[1]);
2809 }
2810 if (!ins_rc[2] && fileObj[2]) {
2811 PyDict_DelItem(_PyPopenProcs,
2812 fileObj[2]);
2813 }
2814 }
2815 }
2816
2817 /*
2818 * Clean up our localized references for the dictionary keys
2819 * and value since PyDict_SetItem will Py_INCREF any copies
2820 * that got placed in the dictionary.
2821 */
2822 Py_XDECREF(procObj);
2823 Py_XDECREF(fileObj[0]);
2824 Py_XDECREF(fileObj[1]);
2825 Py_XDECREF(fileObj[2]);
2826 }
2827
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002828 /* Child is launched. Close the parents copy of those pipe
2829 * handles that only the child should have open. You need to
2830 * make sure that no handles to the write end of the output pipe
2831 * are maintained in this process or else the pipe will not close
2832 * when the child process exits and the ReadFile will hang. */
2833
2834 if (!CloseHandle(hChildStdinRd))
2835 return win32_error("CloseHandle", NULL);
2836
2837 if (!CloseHandle(hChildStdoutWr))
2838 return win32_error("CloseHandle", NULL);
2839
2840 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2841 return win32_error("CloseHandle", NULL);
2842
2843 return f;
2844}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002845
2846/*
2847 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2848 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002849 *
2850 * This function uses the _PyPopenProcs dictionary in order to map the
2851 * input file pointer to information about the process that was
2852 * originally created by the popen* call that created the file pointer.
2853 * The dictionary uses the file pointer as a key (with one entry
2854 * inserted for each file returned by the original popen* call) and a
2855 * single list object as the value for all files from a single call.
2856 * The list object contains the Win32 process handle at [0], and a file
2857 * count at [1], which is initialized to the total number of file
2858 * handles using that list.
2859 *
2860 * This function closes whichever handle it is passed, and decrements
2861 * the file count in the dictionary for the process handle pointed to
2862 * by this file. On the last close (when the file count reaches zero),
2863 * this function will wait for the child process and then return its
2864 * exit code as the result of the close() operation. This permits the
2865 * files to be closed in any order - it is always the close() of the
2866 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002867 */
Tim Peters736aa322000-09-01 06:51:24 +00002868
2869 /* RED_FLAG 31-Aug-2000 Tim
2870 * This is always called (today!) between a pair of
2871 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2872 * macros. So the thread running this has no valid thread state, as
2873 * far as Python is concerned. However, this calls some Python API
2874 * functions that cannot be called safely without a valid thread
2875 * state, in particular PyDict_GetItem.
2876 * As a temporary hack (although it may last for years ...), we
2877 * *rely* on not having a valid thread state in this function, in
2878 * order to create our own "from scratch".
2879 * This will deadlock if _PyPclose is ever called by a thread
2880 * holding the global lock.
2881 */
2882
Fredrik Lundh56055a42000-07-23 19:47:12 +00002883static int _PyPclose(FILE *file)
2884{
Fredrik Lundh20318932000-07-26 17:29:12 +00002885 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002886 DWORD exit_code;
2887 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002888 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2889 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00002890#ifdef WITH_THREAD
2891 PyInterpreterState* pInterpreterState;
2892 PyThreadState* pThreadState;
2893#endif
2894
Fredrik Lundh20318932000-07-26 17:29:12 +00002895 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00002896 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00002897 */
2898 result = fclose(file);
2899
Tim Peters736aa322000-09-01 06:51:24 +00002900#ifdef WITH_THREAD
2901 /* Bootstrap a valid thread state into existence. */
2902 pInterpreterState = PyInterpreterState_New();
2903 if (!pInterpreterState) {
2904 /* Well, we're hosed now! We don't have a thread
2905 * state, so can't call a nice error routine, or raise
2906 * an exception. Just die.
2907 */
2908 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00002909 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002910 return -1; /* unreachable */
2911 }
2912 pThreadState = PyThreadState_New(pInterpreterState);
2913 if (!pThreadState) {
2914 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00002915 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00002916 return -1; /* unreachable */
2917 }
2918 /* Grab the global lock. Note that this will deadlock if the
2919 * current thread already has the lock! (see RED_FLAG comments
2920 * before this function)
2921 */
2922 PyEval_RestoreThread(pThreadState);
2923#endif
2924
Fredrik Lundh56055a42000-07-23 19:47:12 +00002925 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00002926 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2927 (procObj = PyDict_GetItem(_PyPopenProcs,
2928 fileObj)) != NULL &&
2929 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
2930 (intObj = PyList_GetItem(procObj,1)) != NULL) {
2931
2932 hProcess = PyLong_AsVoidPtr(hProcessObj);
2933 file_count = PyInt_AsLong(intObj);
2934
2935 if (file_count > 1) {
2936 /* Still other files referencing process */
2937 file_count--;
2938 PyList_SetItem(procObj,1,
2939 PyInt_FromLong(file_count));
2940 } else {
2941 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00002942 if (result != EOF &&
2943 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
2944 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00002945 /* Possible truncation here in 16-bit environments, but
2946 * real exit codes are just the lower byte in any event.
2947 */
2948 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002949 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00002950 /* Indicate failure - this will cause the file object
2951 * to raise an I/O error and translate the last Win32
2952 * error code from errno. We do have a problem with
2953 * last errors that overlap the normal errno table,
2954 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002955 */
Fredrik Lundh20318932000-07-26 17:29:12 +00002956 if (result != EOF) {
2957 /* If the error wasn't from the fclose(), then
2958 * set errno for the file object error handling.
2959 */
2960 errno = GetLastError();
2961 }
2962 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002963 }
2964
2965 /* Free up the native handle at this point */
2966 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00002967 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00002968
Mark Hammondb37a3732000-08-14 04:47:33 +00002969 /* Remove this file pointer from dictionary */
2970 PyDict_DelItem(_PyPopenProcs, fileObj);
2971
2972 if (PyDict_Size(_PyPopenProcs) == 0) {
2973 Py_DECREF(_PyPopenProcs);
2974 _PyPopenProcs = NULL;
2975 }
2976
2977 } /* if object retrieval ok */
2978
2979 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002980 } /* if _PyPopenProcs */
2981
Tim Peters736aa322000-09-01 06:51:24 +00002982#ifdef WITH_THREAD
2983 /* Tear down the thread & interpreter states.
2984 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00002985 * call the thread clear & delete functions, and indeed insist on
2986 * doing that themselves. The lock must be held during the clear, but
2987 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00002988 */
2989 PyInterpreterState_Clear(pInterpreterState);
2990 PyEval_ReleaseThread(pThreadState);
2991 PyInterpreterState_Delete(pInterpreterState);
2992#endif
2993
Fredrik Lundh56055a42000-07-23 19:47:12 +00002994 return result;
2995}
Tim Peters9acdd3a2000-09-01 19:26:36 +00002996
2997#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00002998static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002999posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003000{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003001 char *name;
3002 char *mode = "r";
3003 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003004 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003005 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003006 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003007 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003008 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003009 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003010 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003011 if (fp == NULL)
3012 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003013 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003014 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003015 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003016 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003017}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003018#endif
3019
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003020#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003022
Guido van Rossumb6775db1994-08-01 11:34:53 +00003023#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003024static char posix_setuid__doc__[] =
3025"setuid(uid) -> None\n\
3026Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003028posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003029{
3030 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003031 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003032 return NULL;
3033 if (setuid(uid) < 0)
3034 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003035 Py_INCREF(Py_None);
3036 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003037}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003038#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003039
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003040
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003041#ifdef HAVE_SETEUID
3042static char posix_seteuid__doc__[] =
3043"seteuid(uid) -> None\n\
3044Set the current process's effective user id.";
3045static PyObject *
3046posix_seteuid (PyObject *self, PyObject *args)
3047{
3048 int euid;
3049 if (!PyArg_ParseTuple(args, "i", &euid)) {
3050 return NULL;
3051 } else if (seteuid(euid) < 0) {
3052 return posix_error();
3053 } else {
3054 Py_INCREF(Py_None);
3055 return Py_None;
3056 }
3057}
3058#endif /* HAVE_SETEUID */
3059
3060#ifdef HAVE_SETEGID
3061static char posix_setegid__doc__[] =
3062"setegid(gid) -> None\n\
3063Set the current process's effective group id.";
3064static PyObject *
3065posix_setegid (PyObject *self, PyObject *args)
3066{
3067 int egid;
3068 if (!PyArg_ParseTuple(args, "i", &egid)) {
3069 return NULL;
3070 } else if (setegid(egid) < 0) {
3071 return posix_error();
3072 } else {
3073 Py_INCREF(Py_None);
3074 return Py_None;
3075 }
3076}
3077#endif /* HAVE_SETEGID */
3078
3079#ifdef HAVE_SETREUID
3080static char posix_setreuid__doc__[] =
3081"seteuid(ruid, euid) -> None\n\
3082Set the current process's real and effective user ids.";
3083static PyObject *
3084posix_setreuid (PyObject *self, PyObject *args)
3085{
3086 int ruid, euid;
3087 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3088 return NULL;
3089 } else if (setreuid(ruid, euid) < 0) {
3090 return posix_error();
3091 } else {
3092 Py_INCREF(Py_None);
3093 return Py_None;
3094 }
3095}
3096#endif /* HAVE_SETREUID */
3097
3098#ifdef HAVE_SETREGID
3099static char posix_setregid__doc__[] =
3100"setegid(rgid, egid) -> None\n\
3101Set the current process's real and effective group ids.";
3102static PyObject *
3103posix_setregid (PyObject *self, PyObject *args)
3104{
3105 int rgid, egid;
3106 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3107 return NULL;
3108 } else if (setregid(rgid, egid) < 0) {
3109 return posix_error();
3110 } else {
3111 Py_INCREF(Py_None);
3112 return Py_None;
3113 }
3114}
3115#endif /* HAVE_SETREGID */
3116
Guido van Rossumb6775db1994-08-01 11:34:53 +00003117#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003118static char posix_setgid__doc__[] =
3119"setgid(gid) -> None\n\
3120Set the current process's group id.";
3121
Barry Warsaw53699e91996-12-10 23:23:01 +00003122static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003123posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003124{
3125 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003126 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003127 return NULL;
3128 if (setgid(gid) < 0)
3129 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003130 Py_INCREF(Py_None);
3131 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003132}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003133#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003134
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003135#ifdef HAVE_SETGROUPS
3136static char posix_setgroups__doc__[] =
3137"setgroups(list) -> None\n\
3138Set the groups of the current process to list.";
3139
3140static PyObject *
3141posix_setgroups(PyObject *self, PyObject *args)
3142{
3143 PyObject *groups;
3144 int i, len;
3145 gid_t grouplist[MAX_GROUPS];
3146
3147 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3148 return NULL;
3149 if (!PySequence_Check(groups)) {
3150 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3151 return NULL;
3152 }
3153 len = PySequence_Size(groups);
3154 if (len > MAX_GROUPS) {
3155 PyErr_SetString(PyExc_ValueError, "too many groups");
3156 return NULL;
3157 }
3158 for(i = 0; i < len; i++) {
3159 PyObject *elem;
3160 elem = PySequence_GetItem(groups, i);
3161 if (!elem)
3162 return NULL;
3163 if (!PyInt_Check(elem)) {
3164 PyErr_SetString(PyExc_TypeError,
3165 "groups must be integers");
3166 Py_DECREF(elem);
3167 return NULL;
3168 }
3169 /* XXX: check that value fits into gid_t. */
3170 grouplist[i] = PyInt_AsLong(elem);
3171 Py_DECREF(elem);
3172 }
3173
3174 if (setgroups(len, grouplist) < 0)
3175 return posix_error();
3176 Py_INCREF(Py_None);
3177 return Py_None;
3178}
3179#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003180
Guido van Rossumb6775db1994-08-01 11:34:53 +00003181#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003182static char posix_waitpid__doc__[] =
3183"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003184Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003185
Barry Warsaw53699e91996-12-10 23:23:01 +00003186static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003187posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003188{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003189 int pid, options;
3190#ifdef UNION_WAIT
3191 union wait status;
3192#define status_i (status.w_status)
3193#else
3194 int status;
3195#define status_i status
3196#endif
3197 status_i = 0;
3198
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003199 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003200 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003201 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003202#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003203 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003204#else
3205 pid = waitpid(pid, &status, options);
3206#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003207 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003208 if (pid == -1)
3209 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003210 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003211 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003212}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003213#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003214
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003215
Guido van Rossumad0ee831995-03-01 10:34:45 +00003216#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003217static char posix_wait__doc__[] =
3218"wait() -> (pid, status)\n\
3219Wait for completion of a child process.";
3220
Barry Warsaw53699e91996-12-10 23:23:01 +00003221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003222posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003223{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003224 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003225#ifdef UNION_WAIT
3226 union wait status;
3227#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003228#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003229 int status;
3230#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003231#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003232 if (!PyArg_ParseTuple(args, ":wait"))
3233 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003234 status_i = 0;
3235 Py_BEGIN_ALLOW_THREADS
3236 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003237 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003238 if (pid == -1)
3239 return posix_error();
3240 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003241 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003242#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003243}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003244#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003246
3247static char posix_lstat__doc__[] =
3248"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3249Like stat(path), but do not follow symbolic links.";
3250
Barry Warsaw53699e91996-12-10 23:23:01 +00003251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003252posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003253{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003254#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003255 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003256#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003257 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003258#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003259}
3260
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003261
Guido van Rossumb6775db1994-08-01 11:34:53 +00003262#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003263static char posix_readlink__doc__[] =
3264"readlink(path) -> path\n\
3265Return a string representing the path to which the symbolic link points.";
3266
Barry Warsaw53699e91996-12-10 23:23:01 +00003267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003268posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003269{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003270 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003271 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003272 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003273 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003274 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003275 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003276 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003277 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003278 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003279 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003280 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003281}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003282#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003283
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284
Guido van Rossumb6775db1994-08-01 11:34:53 +00003285#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003286static char posix_symlink__doc__[] =
3287"symlink(src, dst) -> None\n\
3288Create a symbolic link.";
3289
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003291posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003292{
Mark Hammondef8b6542001-05-13 08:04:26 +00003293 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003294}
3295#endif /* HAVE_SYMLINK */
3296
3297
3298#ifdef HAVE_TIMES
3299#ifndef HZ
3300#define HZ 60 /* Universal constant :-) */
3301#endif /* HZ */
3302
Guido van Rossumd48f2521997-12-05 22:19:34 +00003303#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3304static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003305system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003306{
3307 ULONG value = 0;
3308
3309 Py_BEGIN_ALLOW_THREADS
3310 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3311 Py_END_ALLOW_THREADS
3312
3313 return value;
3314}
3315
3316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003317posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003318{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003319 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003320 return NULL;
3321
3322 /* Currently Only Uptime is Provided -- Others Later */
3323 return Py_BuildValue("ddddd",
3324 (double)0 /* t.tms_utime / HZ */,
3325 (double)0 /* t.tms_stime / HZ */,
3326 (double)0 /* t.tms_cutime / HZ */,
3327 (double)0 /* t.tms_cstime / HZ */,
3328 (double)system_uptime() / 1000);
3329}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003330#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003332posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003333{
3334 struct tms t;
3335 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003336 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003337 return NULL;
3338 errno = 0;
3339 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003340 if (c == (clock_t) -1)
3341 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003342 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003343 (double)t.tms_utime / HZ,
3344 (double)t.tms_stime / HZ,
3345 (double)t.tms_cutime / HZ,
3346 (double)t.tms_cstime / HZ,
3347 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003348}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003349#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003350#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003351
3352
Guido van Rossum87755a21996-09-07 00:59:43 +00003353#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003354#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003356posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003357{
3358 FILETIME create, exit, kernel, user;
3359 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003360 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003361 return NULL;
3362 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003363 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3364 /* The fields of a FILETIME structure are the hi and lo part
3365 of a 64-bit value expressed in 100 nanosecond units.
3366 1e7 is one second in such units; 1e-7 the inverse.
3367 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3368 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003369 return Py_BuildValue(
3370 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003371 (double)(kernel.dwHighDateTime*429.4967296 +
3372 kernel.dwLowDateTime*1e-7),
3373 (double)(user.dwHighDateTime*429.4967296 +
3374 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003375 (double)0,
3376 (double)0,
3377 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003378}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003379#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003380
3381#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003382static char posix_times__doc__[] =
3383"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3384Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003385#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003387
Guido van Rossumb6775db1994-08-01 11:34:53 +00003388#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003389static char posix_setsid__doc__[] =
3390"setsid() -> None\n\
3391Call the system call setsid().";
3392
Barry Warsaw53699e91996-12-10 23:23:01 +00003393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003394posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003395{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003396 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003397 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003398 if (setsid() < 0)
3399 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003400 Py_INCREF(Py_None);
3401 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003402}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003403#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003404
Guido van Rossumb6775db1994-08-01 11:34:53 +00003405#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003406static char posix_setpgid__doc__[] =
3407"setpgid(pid, pgrp) -> None\n\
3408Call the system call setpgid().";
3409
Barry Warsaw53699e91996-12-10 23:23:01 +00003410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003411posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003412{
3413 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003414 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003415 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003416 if (setpgid(pid, pgrp) < 0)
3417 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003418 Py_INCREF(Py_None);
3419 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003420}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003421#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003422
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003423
Guido van Rossumb6775db1994-08-01 11:34:53 +00003424#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003425static char posix_tcgetpgrp__doc__[] =
3426"tcgetpgrp(fd) -> pgid\n\
3427Return the process group associated with the terminal given by a fd.";
3428
Barry Warsaw53699e91996-12-10 23:23:01 +00003429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003430posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003431{
3432 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003433 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003434 return NULL;
3435 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003436 if (pgid < 0)
3437 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003438 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003439}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003440#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003442
Guido van Rossumb6775db1994-08-01 11:34:53 +00003443#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003444static char posix_tcsetpgrp__doc__[] =
3445"tcsetpgrp(fd, pgid) -> None\n\
3446Set the process group associated with the terminal given by a fd.";
3447
Barry Warsaw53699e91996-12-10 23:23:01 +00003448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003449posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003450{
3451 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003452 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003453 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003454 if (tcsetpgrp(fd, pgid) < 0)
3455 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003456 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003457 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003458}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003459#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003460
Guido van Rossum687dd131993-05-17 08:34:16 +00003461/* Functions acting on file descriptors */
3462
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003463static char posix_open__doc__[] =
3464"open(filename, flag [, mode=0777]) -> fd\n\
3465Open a file (for low level IO).";
3466
Barry Warsaw53699e91996-12-10 23:23:01 +00003467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003468posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003469{
Mark Hammondef8b6542001-05-13 08:04:26 +00003470 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003471 int flag;
3472 int mode = 0777;
3473 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003474 if (!PyArg_ParseTuple(args, "eti|i",
3475 Py_FileSystemDefaultEncoding, &file,
3476 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003477 return NULL;
3478
Barry Warsaw53699e91996-12-10 23:23:01 +00003479 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003480 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003481 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003482 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003483 return posix_error_with_allocated_filename(file);
3484 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003485 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003486}
3487
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003488
3489static char posix_close__doc__[] =
3490"close(fd) -> None\n\
3491Close a file descriptor (for low level IO).";
3492
Barry Warsaw53699e91996-12-10 23:23:01 +00003493static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003494posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003495{
3496 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003497 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003498 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003499 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003500 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003501 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003502 if (res < 0)
3503 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003504 Py_INCREF(Py_None);
3505 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003506}
3507
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003508
3509static char posix_dup__doc__[] =
3510"dup(fd) -> fd2\n\
3511Return a duplicate of a file descriptor.";
3512
Barry Warsaw53699e91996-12-10 23:23:01 +00003513static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003514posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003515{
3516 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003517 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003518 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003519 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003520 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003521 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003522 if (fd < 0)
3523 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003524 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003525}
3526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003527
3528static char posix_dup2__doc__[] =
3529"dup2(fd, fd2) -> None\n\
3530Duplicate file descriptor.";
3531
Barry Warsaw53699e91996-12-10 23:23:01 +00003532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003533posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003534{
3535 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003536 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003537 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003538 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003539 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003540 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003541 if (res < 0)
3542 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003543 Py_INCREF(Py_None);
3544 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003545}
3546
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003547
3548static char posix_lseek__doc__[] =
3549"lseek(fd, pos, how) -> newpos\n\
3550Set the current position of a file descriptor.";
3551
Barry Warsaw53699e91996-12-10 23:23:01 +00003552static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003553posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003554{
3555 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003556#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003557 LONG_LONG pos, res;
3558#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003559 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003560#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003561 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003562 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003563 return NULL;
3564#ifdef SEEK_SET
3565 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3566 switch (how) {
3567 case 0: how = SEEK_SET; break;
3568 case 1: how = SEEK_CUR; break;
3569 case 2: how = SEEK_END; break;
3570 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003571#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003572
3573#if !defined(HAVE_LARGEFILE_SUPPORT)
3574 pos = PyInt_AsLong(posobj);
3575#else
3576 pos = PyLong_Check(posobj) ?
3577 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3578#endif
3579 if (PyErr_Occurred())
3580 return NULL;
3581
Barry Warsaw53699e91996-12-10 23:23:01 +00003582 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003583#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003584 res = _lseeki64(fd, pos, how);
3585#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003586 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003587#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003588 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003589 if (res < 0)
3590 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003591
3592#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003593 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003594#else
3595 return PyLong_FromLongLong(res);
3596#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003597}
3598
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003599
3600static char posix_read__doc__[] =
3601"read(fd, buffersize) -> string\n\
3602Read a file descriptor.";
3603
Barry Warsaw53699e91996-12-10 23:23:01 +00003604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003605posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003606{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003607 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003608 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003609 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003610 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003611 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003612 if (buffer == NULL)
3613 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003614 Py_BEGIN_ALLOW_THREADS
3615 n = read(fd, PyString_AsString(buffer), size);
3616 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003617 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003618 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003619 return posix_error();
3620 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003621 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003622 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003623 return buffer;
3624}
3625
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003626
3627static char posix_write__doc__[] =
3628"write(fd, string) -> byteswritten\n\
3629Write a string to a file descriptor.";
3630
Barry Warsaw53699e91996-12-10 23:23:01 +00003631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003632posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003633{
3634 int fd, size;
3635 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003636 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003637 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003638 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003639 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003640 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003641 if (size < 0)
3642 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003643 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003644}
3645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003646
3647static char posix_fstat__doc__[]=
3648"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3649Like stat(), but for an open file descriptor.";
3650
Barry Warsaw53699e91996-12-10 23:23:01 +00003651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003652posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003653{
3654 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003655 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003656 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003657 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003658 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003659 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003660 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003661 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003662 if (res != 0)
3663 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003664
3665 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003666}
3667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003668
3669static char posix_fdopen__doc__[] =
3670"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3671Return an open file object connected to a file descriptor.";
3672
Barry Warsaw53699e91996-12-10 23:23:01 +00003673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003674posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003675{
Guido van Rossum687dd131993-05-17 08:34:16 +00003676 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003677 char *mode = "r";
3678 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003679 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003680 PyObject *f;
3681 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003682 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003683
Barry Warsaw53699e91996-12-10 23:23:01 +00003684 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003685 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003686 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003687 if (fp == NULL)
3688 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003689 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003690 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003691 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003692 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003693}
3694
Skip Montanaro1517d842000-07-19 14:34:14 +00003695static char posix_isatty__doc__[] =
3696"isatty(fd) -> Boolean\n\
3697Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003698connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003699
3700static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003701posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003702{
3703 int fd;
3704 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3705 return NULL;
3706 return Py_BuildValue("i", isatty(fd));
3707}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003708
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003709#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003710static char posix_pipe__doc__[] =
3711"pipe() -> (read_end, write_end)\n\
3712Create a pipe.";
3713
Barry Warsaw53699e91996-12-10 23:23:01 +00003714static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003715posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003716{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003717#if defined(PYOS_OS2)
3718 HFILE read, write;
3719 APIRET rc;
3720
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003721 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003722 return NULL;
3723
3724 Py_BEGIN_ALLOW_THREADS
3725 rc = DosCreatePipe( &read, &write, 4096);
3726 Py_END_ALLOW_THREADS
3727 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003728 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003729
3730 return Py_BuildValue("(ii)", read, write);
3731#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003732#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003733 int fds[2];
3734 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003735 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003736 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003737 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003738 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003739 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003740 if (res != 0)
3741 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003742 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003743#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003744 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003745 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003746 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003747 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003748 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003749 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003750 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003751 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003752 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003753 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003754 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3755 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003756 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003757#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003758#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003759}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003760#endif /* HAVE_PIPE */
3761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003762
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003763#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003764static char posix_mkfifo__doc__[] =
3765"mkfifo(file, [, mode=0666]) -> None\n\
3766Create a FIFO (a POSIX named pipe).";
3767
Barry Warsaw53699e91996-12-10 23:23:01 +00003768static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003769posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003770{
3771 char *file;
3772 int mode = 0666;
3773 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003774 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003775 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003776 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003777 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003778 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003779 if (res < 0)
3780 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003781 Py_INCREF(Py_None);
3782 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003783}
3784#endif
3785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003786
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003787#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003788static char posix_ftruncate__doc__[] =
3789"ftruncate(fd, length) -> None\n\
3790Truncate a file to a specified length.";
3791
Barry Warsaw53699e91996-12-10 23:23:01 +00003792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003793posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003794{
3795 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003796 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003797 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003798 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003799
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003800 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003801 return NULL;
3802
3803#if !defined(HAVE_LARGEFILE_SUPPORT)
3804 length = PyInt_AsLong(lenobj);
3805#else
3806 length = PyLong_Check(lenobj) ?
3807 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3808#endif
3809 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003810 return NULL;
3811
Barry Warsaw53699e91996-12-10 23:23:01 +00003812 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003813 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003814 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003815 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003816 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003817 return NULL;
3818 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003819 Py_INCREF(Py_None);
3820 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003821}
3822#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003823
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003824#ifdef NeXT
3825#define HAVE_PUTENV
3826/* Steve Spicklemire got this putenv from NeXTAnswers */
3827static int
3828putenv(char *newval)
3829{
3830 extern char **environ;
3831
3832 static int firstTime = 1;
3833 char **ep;
3834 char *cp;
3835 int esiz;
3836 char *np;
3837
3838 if (!(np = strchr(newval, '=')))
3839 return 1;
3840 *np = '\0';
3841
3842 /* look it up */
3843 for (ep=environ ; *ep ; ep++)
3844 {
3845 /* this should always be true... */
3846 if (cp = strchr(*ep, '='))
3847 {
3848 *cp = '\0';
3849 if (!strcmp(*ep, newval))
3850 {
3851 /* got it! */
3852 *cp = '=';
3853 break;
3854 }
3855 *cp = '=';
3856 }
3857 else
3858 {
3859 *np = '=';
3860 return 1;
3861 }
3862 }
3863
3864 *np = '=';
3865 if (*ep)
3866 {
3867 /* the string was already there:
3868 just replace it with the new one */
3869 *ep = newval;
3870 return 0;
3871 }
3872
3873 /* expand environ by one */
3874 for (esiz=2, ep=environ ; *ep ; ep++)
3875 esiz++;
3876 if (firstTime)
3877 {
3878 char **epp;
3879 char **newenv;
3880 if (!(newenv = malloc(esiz * sizeof(char *))))
3881 return 1;
3882
3883 for (ep=environ, epp=newenv ; *ep ;)
3884 *epp++ = *ep++;
3885 *epp++ = newval;
3886 *epp = (char *) 0;
3887 environ = newenv;
3888 }
3889 else
3890 {
3891 if (!(environ = realloc(environ, esiz * sizeof(char *))))
3892 return 1;
3893 environ[esiz - 2] = newval;
3894 environ[esiz - 1] = (char *) 0;
3895 firstTime = 0;
3896 }
3897
3898 return 0;
3899}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00003900#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003901
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003902
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003903#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003904static char posix_putenv__doc__[] =
3905"putenv(key, value) -> None\n\
3906Change or add an environment variable.";
3907
Fred Drake762e2061999-08-26 17:23:54 +00003908/* Save putenv() parameters as values here, so we can collect them when they
3909 * get re-set with another call for the same key. */
3910static PyObject *posix_putenv_garbage;
3911
Barry Warsaw53699e91996-12-10 23:23:01 +00003912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003913posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003914{
3915 char *s1, *s2;
3916 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003917 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003918
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003919 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003920 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003921
3922#if defined(PYOS_OS2)
3923 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3924 APIRET rc;
3925
3926 if (strlen(s2) == 0) /* If New Value is an Empty String */
3927 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3928
3929 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3930 if (rc != NO_ERROR)
3931 return os2_error(rc);
3932
3933 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3934 APIRET rc;
3935
3936 if (strlen(s2) == 0) /* If New Value is an Empty String */
3937 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3938
3939 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3940 if (rc != NO_ERROR)
3941 return os2_error(rc);
3942 } else {
3943#endif
3944
Fred Drake762e2061999-08-26 17:23:54 +00003945 /* XXX This can leak memory -- not easy to fix :-( */
3946 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3947 if (newstr == NULL)
3948 return PyErr_NoMemory();
3949 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003950 (void) sprintf(new, "%s=%s", s1, s2);
3951 if (putenv(new)) {
3952 posix_error();
3953 return NULL;
3954 }
Fred Drake762e2061999-08-26 17:23:54 +00003955 /* Install the first arg and newstr in posix_putenv_garbage;
3956 * this will cause previous value to be collected. This has to
3957 * happen after the real putenv() call because the old value
3958 * was still accessible until then. */
3959 if (PyDict_SetItem(posix_putenv_garbage,
3960 PyTuple_GET_ITEM(args, 0), newstr)) {
3961 /* really not much we can do; just leak */
3962 PyErr_Clear();
3963 }
3964 else {
3965 Py_DECREF(newstr);
3966 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00003967
3968#if defined(PYOS_OS2)
3969 }
3970#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003971 Py_INCREF(Py_None);
3972 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003973}
Guido van Rossumb6a47161997-09-15 22:54:34 +00003974#endif /* putenv */
3975
3976#ifdef HAVE_STRERROR
3977static char posix_strerror__doc__[] =
3978"strerror(code) -> string\n\
3979Translate an error code to a message string.";
3980
Guido van Rossumf68d8e52001-04-14 17:55:09 +00003981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003982posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00003983{
3984 int code;
3985 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003986 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00003987 return NULL;
3988 message = strerror(code);
3989 if (message == NULL) {
3990 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00003991 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00003992 return NULL;
3993 }
3994 return PyString_FromString(message);
3995}
3996#endif /* strerror */
3997
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003998
Guido van Rossumc9641791998-08-04 15:26:23 +00003999#ifdef HAVE_SYS_WAIT_H
4000
4001#ifdef WIFSTOPPED
4002static char posix_WIFSTOPPED__doc__[] =
4003"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004004Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004005
4006static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004007posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004008{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004009#ifdef UNION_WAIT
4010 union wait status;
4011#define status_i (status.w_status)
4012#else
4013 int status;
4014#define status_i status
4015#endif
4016 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004017
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004018 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004019 {
4020 return NULL;
4021 }
4022
4023 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004024#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004025}
4026#endif /* WIFSTOPPED */
4027
4028#ifdef WIFSIGNALED
4029static char posix_WIFSIGNALED__doc__[] =
4030"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004031Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004032
4033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004034posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004035{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004036#ifdef UNION_WAIT
4037 union wait status;
4038#define status_i (status.w_status)
4039#else
4040 int status;
4041#define status_i status
4042#endif
4043 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004044
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004045 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004046 {
4047 return NULL;
4048 }
4049
4050 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004051#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004052}
4053#endif /* WIFSIGNALED */
4054
4055#ifdef WIFEXITED
4056static char posix_WIFEXITED__doc__[] =
4057"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004058Return true if the process returning 'status' exited using the exit()\n\
4059system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004060
4061static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004062posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004063{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004064#ifdef UNION_WAIT
4065 union wait status;
4066#define status_i (status.w_status)
4067#else
4068 int status;
4069#define status_i status
4070#endif
4071 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004072
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004073 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004074 {
4075 return NULL;
4076 }
4077
4078 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004079#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004080}
4081#endif /* WIFEXITED */
4082
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004083#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004084static char posix_WEXITSTATUS__doc__[] =
4085"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004086Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004087
4088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004089posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004090{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004091#ifdef UNION_WAIT
4092 union wait status;
4093#define status_i (status.w_status)
4094#else
4095 int status;
4096#define status_i status
4097#endif
4098 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004099
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004100 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004101 {
4102 return NULL;
4103 }
4104
4105 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004106#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004107}
4108#endif /* WEXITSTATUS */
4109
4110#ifdef WTERMSIG
4111static char posix_WTERMSIG__doc__[] =
4112"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004113Return the signal that terminated the process that provided the 'status'\n\
4114value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004115
4116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004117posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004118{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004119#ifdef UNION_WAIT
4120 union wait status;
4121#define status_i (status.w_status)
4122#else
4123 int status;
4124#define status_i status
4125#endif
4126 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004127
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004128 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004129 {
4130 return NULL;
4131 }
4132
4133 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004134#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004135}
4136#endif /* WTERMSIG */
4137
4138#ifdef WSTOPSIG
4139static char posix_WSTOPSIG__doc__[] =
4140"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004141Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004142
4143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004144posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004145{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004146#ifdef UNION_WAIT
4147 union wait status;
4148#define status_i (status.w_status)
4149#else
4150 int status;
4151#define status_i status
4152#endif
4153 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004154
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004155 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004156 {
4157 return NULL;
4158 }
4159
4160 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004161#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004162}
4163#endif /* WSTOPSIG */
4164
4165#endif /* HAVE_SYS_WAIT_H */
4166
4167
Guido van Rossum94f6f721999-01-06 18:42:14 +00004168#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004169#ifdef _SCO_DS
4170/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4171 needed definitions in sys/statvfs.h */
4172#define _SVID3
4173#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004174#include <sys/statvfs.h>
4175
4176static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004177"fstatvfs(fd) -> \n\
4178 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004179Perform an fstatvfs system call on the given fd.";
4180
4181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004182posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004183{
4184 int fd, res;
4185 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004186 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004187 return NULL;
4188 Py_BEGIN_ALLOW_THREADS
4189 res = fstatvfs(fd, &st);
4190 Py_END_ALLOW_THREADS
4191 if (res != 0)
4192 return posix_error();
4193#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004194 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004195 (long) st.f_bsize,
4196 (long) st.f_frsize,
4197 (long) st.f_blocks,
4198 (long) st.f_bfree,
4199 (long) st.f_bavail,
4200 (long) st.f_files,
4201 (long) st.f_ffree,
4202 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004203 (long) st.f_flag,
4204 (long) st.f_namemax);
4205#else
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004206 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004207 (long) st.f_bsize,
4208 (long) st.f_frsize,
4209 (LONG_LONG) st.f_blocks,
4210 (LONG_LONG) st.f_bfree,
4211 (LONG_LONG) st.f_bavail,
4212 (LONG_LONG) st.f_files,
4213 (LONG_LONG) st.f_ffree,
4214 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004215 (long) st.f_flag,
4216 (long) st.f_namemax);
4217#endif
4218}
4219#endif /* HAVE_FSTATVFS */
4220
4221
4222#if defined(HAVE_STATVFS)
4223#include <sys/statvfs.h>
4224
4225static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004226"statvfs(path) -> \n\
4227 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004228Perform a statvfs system call on the given path.";
4229
4230static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004231posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004232{
4233 char *path;
4234 int res;
4235 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004236 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004237 return NULL;
4238 Py_BEGIN_ALLOW_THREADS
4239 res = statvfs(path, &st);
4240 Py_END_ALLOW_THREADS
4241 if (res != 0)
4242 return posix_error_with_filename(path);
4243#if !defined(HAVE_LARGEFILE_SUPPORT)
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004244 return Py_BuildValue("(llllllllll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004245 (long) st.f_bsize,
4246 (long) st.f_frsize,
4247 (long) st.f_blocks,
4248 (long) st.f_bfree,
4249 (long) st.f_bavail,
4250 (long) st.f_files,
4251 (long) st.f_ffree,
4252 (long) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004253 (long) st.f_flag,
4254 (long) st.f_namemax);
4255#else /* HAVE_LARGEFILE_SUPPORT */
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004256 return Py_BuildValue("(llLLLLLLll)",
Guido van Rossum94f6f721999-01-06 18:42:14 +00004257 (long) st.f_bsize,
4258 (long) st.f_frsize,
4259 (LONG_LONG) st.f_blocks,
4260 (LONG_LONG) st.f_bfree,
4261 (LONG_LONG) st.f_bavail,
4262 (LONG_LONG) st.f_files,
4263 (LONG_LONG) st.f_ffree,
4264 (LONG_LONG) st.f_favail,
Guido van Rossum94f6f721999-01-06 18:42:14 +00004265 (long) st.f_flag,
4266 (long) st.f_namemax);
4267#endif
4268}
4269#endif /* HAVE_STATVFS */
4270
4271
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004272#ifdef HAVE_TEMPNAM
4273static char posix_tempnam__doc__[] = "\
4274tempnam([dir[, prefix]]) -> string\n\
4275Return a unique name for a temporary file.\n\
4276The directory and a short may be specified as strings; they may be omitted\n\
4277or None if not needed.";
4278
4279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004280posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004281{
4282 PyObject *result = NULL;
4283 char *dir = NULL;
4284 char *pfx = NULL;
4285 char *name;
4286
4287 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4288 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004289
4290 if (PyErr_Warn(PyExc_RuntimeWarning,
4291 "tempnam is a potential security risk to your program") < 0)
4292 return NULL;
4293
Fred Drake78b71c22001-07-17 20:37:36 +00004294#ifdef MS_WIN32
4295 name = _tempnam(dir, pfx);
4296#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004297 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004298#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004299 if (name == NULL)
4300 return PyErr_NoMemory();
4301 result = PyString_FromString(name);
4302 free(name);
4303 return result;
4304}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004305#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004306
4307
4308#ifdef HAVE_TMPFILE
4309static char posix_tmpfile__doc__[] = "\
4310tmpfile() -> file object\n\
4311Create a temporary file with no directory entries.";
4312
4313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004314posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004315{
4316 FILE *fp;
4317
4318 if (!PyArg_ParseTuple(args, ":tmpfile"))
4319 return NULL;
4320 fp = tmpfile();
4321 if (fp == NULL)
4322 return posix_error();
4323 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4324}
4325#endif
4326
4327
4328#ifdef HAVE_TMPNAM
4329static char posix_tmpnam__doc__[] = "\
4330tmpnam() -> string\n\
4331Return a unique name for a temporary file.";
4332
4333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004334posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004335{
4336 char buffer[L_tmpnam];
4337 char *name;
4338
4339 if (!PyArg_ParseTuple(args, ":tmpnam"))
4340 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004341
4342 if (PyErr_Warn(PyExc_RuntimeWarning,
4343 "tmpnam is a potential security risk to your program") < 0)
4344 return NULL;
4345
Greg Wardb48bc172000-03-01 21:51:56 +00004346#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004347 name = tmpnam_r(buffer);
4348#else
4349 name = tmpnam(buffer);
4350#endif
4351 if (name == NULL) {
4352 PyErr_SetObject(PyExc_OSError,
4353 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004354#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004355 "unexpected NULL from tmpnam_r"
4356#else
4357 "unexpected NULL from tmpnam"
4358#endif
4359 ));
4360 return NULL;
4361 }
4362 return PyString_FromString(buffer);
4363}
4364#endif
4365
4366
Fred Drakec9680921999-12-13 16:37:25 +00004367/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4368 * It maps strings representing configuration variable names to
4369 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004370 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004371 * rarely-used constants. There are three separate tables that use
4372 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004373 *
4374 * This code is always included, even if none of the interfaces that
4375 * need it are included. The #if hackery needed to avoid it would be
4376 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004377 */
4378struct constdef {
4379 char *name;
4380 long value;
4381};
4382
Fred Drake12c6e2d1999-12-14 21:25:03 +00004383static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004384conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4385 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004386{
4387 if (PyInt_Check(arg)) {
4388 *valuep = PyInt_AS_LONG(arg);
4389 return 1;
4390 }
4391 if (PyString_Check(arg)) {
4392 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004393 size_t lo = 0;
4394 size_t mid;
4395 size_t hi = tablesize;
4396 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004397 char *confname = PyString_AS_STRING(arg);
4398 while (lo < hi) {
4399 mid = (lo + hi) / 2;
4400 cmp = strcmp(confname, table[mid].name);
4401 if (cmp < 0)
4402 hi = mid;
4403 else if (cmp > 0)
4404 lo = mid + 1;
4405 else {
4406 *valuep = table[mid].value;
4407 return 1;
4408 }
4409 }
4410 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4411 }
4412 else
4413 PyErr_SetString(PyExc_TypeError,
4414 "configuration names must be strings or integers");
4415 return 0;
4416}
4417
4418
4419#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4420static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004421#ifdef _PC_ABI_AIO_XFER_MAX
4422 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4423#endif
4424#ifdef _PC_ABI_ASYNC_IO
4425 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4426#endif
Fred Drakec9680921999-12-13 16:37:25 +00004427#ifdef _PC_ASYNC_IO
4428 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4429#endif
4430#ifdef _PC_CHOWN_RESTRICTED
4431 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4432#endif
4433#ifdef _PC_FILESIZEBITS
4434 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4435#endif
4436#ifdef _PC_LAST
4437 {"PC_LAST", _PC_LAST},
4438#endif
4439#ifdef _PC_LINK_MAX
4440 {"PC_LINK_MAX", _PC_LINK_MAX},
4441#endif
4442#ifdef _PC_MAX_CANON
4443 {"PC_MAX_CANON", _PC_MAX_CANON},
4444#endif
4445#ifdef _PC_MAX_INPUT
4446 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4447#endif
4448#ifdef _PC_NAME_MAX
4449 {"PC_NAME_MAX", _PC_NAME_MAX},
4450#endif
4451#ifdef _PC_NO_TRUNC
4452 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4453#endif
4454#ifdef _PC_PATH_MAX
4455 {"PC_PATH_MAX", _PC_PATH_MAX},
4456#endif
4457#ifdef _PC_PIPE_BUF
4458 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4459#endif
4460#ifdef _PC_PRIO_IO
4461 {"PC_PRIO_IO", _PC_PRIO_IO},
4462#endif
4463#ifdef _PC_SOCK_MAXBUF
4464 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4465#endif
4466#ifdef _PC_SYNC_IO
4467 {"PC_SYNC_IO", _PC_SYNC_IO},
4468#endif
4469#ifdef _PC_VDISABLE
4470 {"PC_VDISABLE", _PC_VDISABLE},
4471#endif
4472};
4473
Fred Drakec9680921999-12-13 16:37:25 +00004474static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004475conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004476{
4477 return conv_confname(arg, valuep, posix_constants_pathconf,
4478 sizeof(posix_constants_pathconf)
4479 / sizeof(struct constdef));
4480}
4481#endif
4482
4483#ifdef HAVE_FPATHCONF
4484static char posix_fpathconf__doc__[] = "\
4485fpathconf(fd, name) -> integer\n\
4486Return the configuration limit name for the file descriptor fd.\n\
4487If there is no limit, return -1.";
4488
4489static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004490posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004491{
4492 PyObject *result = NULL;
4493 int name, fd;
4494
Fred Drake12c6e2d1999-12-14 21:25:03 +00004495 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4496 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004497 long limit;
4498
4499 errno = 0;
4500 limit = fpathconf(fd, name);
4501 if (limit == -1 && errno != 0)
4502 posix_error();
4503 else
4504 result = PyInt_FromLong(limit);
4505 }
4506 return result;
4507}
4508#endif
4509
4510
4511#ifdef HAVE_PATHCONF
4512static char posix_pathconf__doc__[] = "\
4513pathconf(path, name) -> integer\n\
4514Return the configuration limit name for the file or directory path.\n\
4515If there is no limit, return -1.";
4516
4517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004518posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004519{
4520 PyObject *result = NULL;
4521 int name;
4522 char *path;
4523
4524 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4525 conv_path_confname, &name)) {
4526 long limit;
4527
4528 errno = 0;
4529 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004530 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004531 if (errno == EINVAL)
4532 /* could be a path or name problem */
4533 posix_error();
4534 else
4535 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004536 }
Fred Drakec9680921999-12-13 16:37:25 +00004537 else
4538 result = PyInt_FromLong(limit);
4539 }
4540 return result;
4541}
4542#endif
4543
4544#ifdef HAVE_CONFSTR
4545static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004546#ifdef _CS_ARCHITECTURE
4547 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4548#endif
4549#ifdef _CS_HOSTNAME
4550 {"CS_HOSTNAME", _CS_HOSTNAME},
4551#endif
4552#ifdef _CS_HW_PROVIDER
4553 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4554#endif
4555#ifdef _CS_HW_SERIAL
4556 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4557#endif
4558#ifdef _CS_INITTAB_NAME
4559 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4560#endif
Fred Drakec9680921999-12-13 16:37:25 +00004561#ifdef _CS_LFS64_CFLAGS
4562 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4563#endif
4564#ifdef _CS_LFS64_LDFLAGS
4565 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4566#endif
4567#ifdef _CS_LFS64_LIBS
4568 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4569#endif
4570#ifdef _CS_LFS64_LINTFLAGS
4571 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4572#endif
4573#ifdef _CS_LFS_CFLAGS
4574 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4575#endif
4576#ifdef _CS_LFS_LDFLAGS
4577 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4578#endif
4579#ifdef _CS_LFS_LIBS
4580 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4581#endif
4582#ifdef _CS_LFS_LINTFLAGS
4583 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4584#endif
Fred Draked86ed291999-12-15 15:34:33 +00004585#ifdef _CS_MACHINE
4586 {"CS_MACHINE", _CS_MACHINE},
4587#endif
Fred Drakec9680921999-12-13 16:37:25 +00004588#ifdef _CS_PATH
4589 {"CS_PATH", _CS_PATH},
4590#endif
Fred Draked86ed291999-12-15 15:34:33 +00004591#ifdef _CS_RELEASE
4592 {"CS_RELEASE", _CS_RELEASE},
4593#endif
4594#ifdef _CS_SRPC_DOMAIN
4595 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4596#endif
4597#ifdef _CS_SYSNAME
4598 {"CS_SYSNAME", _CS_SYSNAME},
4599#endif
4600#ifdef _CS_VERSION
4601 {"CS_VERSION", _CS_VERSION},
4602#endif
Fred Drakec9680921999-12-13 16:37:25 +00004603#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4604 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4605#endif
4606#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4607 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4608#endif
4609#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4610 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4611#endif
4612#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4613 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4614#endif
4615#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4616 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4617#endif
4618#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4619 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4620#endif
4621#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4622 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4623#endif
4624#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4625 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4626#endif
4627#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4628 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4629#endif
4630#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4631 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4632#endif
4633#ifdef _CS_XBS5_LP64_OFF64_LIBS
4634 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4635#endif
4636#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4637 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4638#endif
4639#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4640 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4641#endif
4642#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4643 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4644#endif
4645#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4646 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4647#endif
4648#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4649 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4650#endif
Fred Draked86ed291999-12-15 15:34:33 +00004651#ifdef _MIPS_CS_AVAIL_PROCESSORS
4652 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4653#endif
4654#ifdef _MIPS_CS_BASE
4655 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4656#endif
4657#ifdef _MIPS_CS_HOSTID
4658 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4659#endif
4660#ifdef _MIPS_CS_HW_NAME
4661 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4662#endif
4663#ifdef _MIPS_CS_NUM_PROCESSORS
4664 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4665#endif
4666#ifdef _MIPS_CS_OSREL_MAJ
4667 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4668#endif
4669#ifdef _MIPS_CS_OSREL_MIN
4670 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4671#endif
4672#ifdef _MIPS_CS_OSREL_PATCH
4673 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4674#endif
4675#ifdef _MIPS_CS_OS_NAME
4676 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4677#endif
4678#ifdef _MIPS_CS_OS_PROVIDER
4679 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4680#endif
4681#ifdef _MIPS_CS_PROCESSORS
4682 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4683#endif
4684#ifdef _MIPS_CS_SERIAL
4685 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4686#endif
4687#ifdef _MIPS_CS_VENDOR
4688 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4689#endif
Fred Drakec9680921999-12-13 16:37:25 +00004690};
4691
4692static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004693conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004694{
4695 return conv_confname(arg, valuep, posix_constants_confstr,
4696 sizeof(posix_constants_confstr)
4697 / sizeof(struct constdef));
4698}
4699
4700static char posix_confstr__doc__[] = "\
4701confstr(name) -> string\n\
4702Return a string-valued system configuration variable.";
4703
4704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004705posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004706{
4707 PyObject *result = NULL;
4708 int name;
4709 char buffer[64];
4710
4711 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4712 int len = confstr(name, buffer, sizeof(buffer));
4713
Fred Drakec9680921999-12-13 16:37:25 +00004714 errno = 0;
4715 if (len == 0) {
4716 if (errno != 0)
4717 posix_error();
4718 else
4719 result = PyString_FromString("");
4720 }
4721 else {
4722 if (len >= sizeof(buffer)) {
4723 result = PyString_FromStringAndSize(NULL, len);
4724 if (result != NULL)
4725 confstr(name, PyString_AS_STRING(result), len+1);
4726 }
4727 else
4728 result = PyString_FromString(buffer);
4729 }
4730 }
4731 return result;
4732}
4733#endif
4734
4735
4736#ifdef HAVE_SYSCONF
4737static struct constdef posix_constants_sysconf[] = {
4738#ifdef _SC_2_CHAR_TERM
4739 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4740#endif
4741#ifdef _SC_2_C_BIND
4742 {"SC_2_C_BIND", _SC_2_C_BIND},
4743#endif
4744#ifdef _SC_2_C_DEV
4745 {"SC_2_C_DEV", _SC_2_C_DEV},
4746#endif
4747#ifdef _SC_2_C_VERSION
4748 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4749#endif
4750#ifdef _SC_2_FORT_DEV
4751 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4752#endif
4753#ifdef _SC_2_FORT_RUN
4754 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4755#endif
4756#ifdef _SC_2_LOCALEDEF
4757 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4758#endif
4759#ifdef _SC_2_SW_DEV
4760 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4761#endif
4762#ifdef _SC_2_UPE
4763 {"SC_2_UPE", _SC_2_UPE},
4764#endif
4765#ifdef _SC_2_VERSION
4766 {"SC_2_VERSION", _SC_2_VERSION},
4767#endif
Fred Draked86ed291999-12-15 15:34:33 +00004768#ifdef _SC_ABI_ASYNCHRONOUS_IO
4769 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4770#endif
4771#ifdef _SC_ACL
4772 {"SC_ACL", _SC_ACL},
4773#endif
Fred Drakec9680921999-12-13 16:37:25 +00004774#ifdef _SC_AIO_LISTIO_MAX
4775 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4776#endif
Fred Drakec9680921999-12-13 16:37:25 +00004777#ifdef _SC_AIO_MAX
4778 {"SC_AIO_MAX", _SC_AIO_MAX},
4779#endif
4780#ifdef _SC_AIO_PRIO_DELTA_MAX
4781 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4782#endif
4783#ifdef _SC_ARG_MAX
4784 {"SC_ARG_MAX", _SC_ARG_MAX},
4785#endif
4786#ifdef _SC_ASYNCHRONOUS_IO
4787 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4788#endif
4789#ifdef _SC_ATEXIT_MAX
4790 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4791#endif
Fred Draked86ed291999-12-15 15:34:33 +00004792#ifdef _SC_AUDIT
4793 {"SC_AUDIT", _SC_AUDIT},
4794#endif
Fred Drakec9680921999-12-13 16:37:25 +00004795#ifdef _SC_AVPHYS_PAGES
4796 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4797#endif
4798#ifdef _SC_BC_BASE_MAX
4799 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4800#endif
4801#ifdef _SC_BC_DIM_MAX
4802 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4803#endif
4804#ifdef _SC_BC_SCALE_MAX
4805 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4806#endif
4807#ifdef _SC_BC_STRING_MAX
4808 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4809#endif
Fred Draked86ed291999-12-15 15:34:33 +00004810#ifdef _SC_CAP
4811 {"SC_CAP", _SC_CAP},
4812#endif
Fred Drakec9680921999-12-13 16:37:25 +00004813#ifdef _SC_CHARCLASS_NAME_MAX
4814 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4815#endif
4816#ifdef _SC_CHAR_BIT
4817 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4818#endif
4819#ifdef _SC_CHAR_MAX
4820 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4821#endif
4822#ifdef _SC_CHAR_MIN
4823 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4824#endif
4825#ifdef _SC_CHILD_MAX
4826 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4827#endif
4828#ifdef _SC_CLK_TCK
4829 {"SC_CLK_TCK", _SC_CLK_TCK},
4830#endif
4831#ifdef _SC_COHER_BLKSZ
4832 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4833#endif
4834#ifdef _SC_COLL_WEIGHTS_MAX
4835 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4836#endif
4837#ifdef _SC_DCACHE_ASSOC
4838 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4839#endif
4840#ifdef _SC_DCACHE_BLKSZ
4841 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4842#endif
4843#ifdef _SC_DCACHE_LINESZ
4844 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4845#endif
4846#ifdef _SC_DCACHE_SZ
4847 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4848#endif
4849#ifdef _SC_DCACHE_TBLKSZ
4850 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4851#endif
4852#ifdef _SC_DELAYTIMER_MAX
4853 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4854#endif
4855#ifdef _SC_EQUIV_CLASS_MAX
4856 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4857#endif
4858#ifdef _SC_EXPR_NEST_MAX
4859 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4860#endif
4861#ifdef _SC_FSYNC
4862 {"SC_FSYNC", _SC_FSYNC},
4863#endif
4864#ifdef _SC_GETGR_R_SIZE_MAX
4865 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4866#endif
4867#ifdef _SC_GETPW_R_SIZE_MAX
4868 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4869#endif
4870#ifdef _SC_ICACHE_ASSOC
4871 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4872#endif
4873#ifdef _SC_ICACHE_BLKSZ
4874 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4875#endif
4876#ifdef _SC_ICACHE_LINESZ
4877 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4878#endif
4879#ifdef _SC_ICACHE_SZ
4880 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4881#endif
Fred Draked86ed291999-12-15 15:34:33 +00004882#ifdef _SC_INF
4883 {"SC_INF", _SC_INF},
4884#endif
Fred Drakec9680921999-12-13 16:37:25 +00004885#ifdef _SC_INT_MAX
4886 {"SC_INT_MAX", _SC_INT_MAX},
4887#endif
4888#ifdef _SC_INT_MIN
4889 {"SC_INT_MIN", _SC_INT_MIN},
4890#endif
4891#ifdef _SC_IOV_MAX
4892 {"SC_IOV_MAX", _SC_IOV_MAX},
4893#endif
Fred Draked86ed291999-12-15 15:34:33 +00004894#ifdef _SC_IP_SECOPTS
4895 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4896#endif
Fred Drakec9680921999-12-13 16:37:25 +00004897#ifdef _SC_JOB_CONTROL
4898 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4899#endif
Fred Draked86ed291999-12-15 15:34:33 +00004900#ifdef _SC_KERN_POINTERS
4901 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4902#endif
4903#ifdef _SC_KERN_SIM
4904 {"SC_KERN_SIM", _SC_KERN_SIM},
4905#endif
Fred Drakec9680921999-12-13 16:37:25 +00004906#ifdef _SC_LINE_MAX
4907 {"SC_LINE_MAX", _SC_LINE_MAX},
4908#endif
4909#ifdef _SC_LOGIN_NAME_MAX
4910 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4911#endif
4912#ifdef _SC_LOGNAME_MAX
4913 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
4914#endif
4915#ifdef _SC_LONG_BIT
4916 {"SC_LONG_BIT", _SC_LONG_BIT},
4917#endif
Fred Draked86ed291999-12-15 15:34:33 +00004918#ifdef _SC_MAC
4919 {"SC_MAC", _SC_MAC},
4920#endif
Fred Drakec9680921999-12-13 16:37:25 +00004921#ifdef _SC_MAPPED_FILES
4922 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
4923#endif
4924#ifdef _SC_MAXPID
4925 {"SC_MAXPID", _SC_MAXPID},
4926#endif
4927#ifdef _SC_MB_LEN_MAX
4928 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
4929#endif
4930#ifdef _SC_MEMLOCK
4931 {"SC_MEMLOCK", _SC_MEMLOCK},
4932#endif
4933#ifdef _SC_MEMLOCK_RANGE
4934 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
4935#endif
4936#ifdef _SC_MEMORY_PROTECTION
4937 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
4938#endif
4939#ifdef _SC_MESSAGE_PASSING
4940 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
4941#endif
Fred Draked86ed291999-12-15 15:34:33 +00004942#ifdef _SC_MMAP_FIXED_ALIGNMENT
4943 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
4944#endif
Fred Drakec9680921999-12-13 16:37:25 +00004945#ifdef _SC_MQ_OPEN_MAX
4946 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
4947#endif
4948#ifdef _SC_MQ_PRIO_MAX
4949 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
4950#endif
Fred Draked86ed291999-12-15 15:34:33 +00004951#ifdef _SC_NACLS_MAX
4952 {"SC_NACLS_MAX", _SC_NACLS_MAX},
4953#endif
Fred Drakec9680921999-12-13 16:37:25 +00004954#ifdef _SC_NGROUPS_MAX
4955 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
4956#endif
4957#ifdef _SC_NL_ARGMAX
4958 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
4959#endif
4960#ifdef _SC_NL_LANGMAX
4961 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
4962#endif
4963#ifdef _SC_NL_MSGMAX
4964 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
4965#endif
4966#ifdef _SC_NL_NMAX
4967 {"SC_NL_NMAX", _SC_NL_NMAX},
4968#endif
4969#ifdef _SC_NL_SETMAX
4970 {"SC_NL_SETMAX", _SC_NL_SETMAX},
4971#endif
4972#ifdef _SC_NL_TEXTMAX
4973 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
4974#endif
4975#ifdef _SC_NPROCESSORS_CONF
4976 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
4977#endif
4978#ifdef _SC_NPROCESSORS_ONLN
4979 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
4980#endif
Fred Draked86ed291999-12-15 15:34:33 +00004981#ifdef _SC_NPROC_CONF
4982 {"SC_NPROC_CONF", _SC_NPROC_CONF},
4983#endif
4984#ifdef _SC_NPROC_ONLN
4985 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
4986#endif
Fred Drakec9680921999-12-13 16:37:25 +00004987#ifdef _SC_NZERO
4988 {"SC_NZERO", _SC_NZERO},
4989#endif
4990#ifdef _SC_OPEN_MAX
4991 {"SC_OPEN_MAX", _SC_OPEN_MAX},
4992#endif
4993#ifdef _SC_PAGESIZE
4994 {"SC_PAGESIZE", _SC_PAGESIZE},
4995#endif
4996#ifdef _SC_PAGE_SIZE
4997 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
4998#endif
4999#ifdef _SC_PASS_MAX
5000 {"SC_PASS_MAX", _SC_PASS_MAX},
5001#endif
5002#ifdef _SC_PHYS_PAGES
5003 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5004#endif
5005#ifdef _SC_PII
5006 {"SC_PII", _SC_PII},
5007#endif
5008#ifdef _SC_PII_INTERNET
5009 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5010#endif
5011#ifdef _SC_PII_INTERNET_DGRAM
5012 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5013#endif
5014#ifdef _SC_PII_INTERNET_STREAM
5015 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5016#endif
5017#ifdef _SC_PII_OSI
5018 {"SC_PII_OSI", _SC_PII_OSI},
5019#endif
5020#ifdef _SC_PII_OSI_CLTS
5021 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5022#endif
5023#ifdef _SC_PII_OSI_COTS
5024 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5025#endif
5026#ifdef _SC_PII_OSI_M
5027 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5028#endif
5029#ifdef _SC_PII_SOCKET
5030 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5031#endif
5032#ifdef _SC_PII_XTI
5033 {"SC_PII_XTI", _SC_PII_XTI},
5034#endif
5035#ifdef _SC_POLL
5036 {"SC_POLL", _SC_POLL},
5037#endif
5038#ifdef _SC_PRIORITIZED_IO
5039 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5040#endif
5041#ifdef _SC_PRIORITY_SCHEDULING
5042 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5043#endif
5044#ifdef _SC_REALTIME_SIGNALS
5045 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5046#endif
5047#ifdef _SC_RE_DUP_MAX
5048 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5049#endif
5050#ifdef _SC_RTSIG_MAX
5051 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5052#endif
5053#ifdef _SC_SAVED_IDS
5054 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5055#endif
5056#ifdef _SC_SCHAR_MAX
5057 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5058#endif
5059#ifdef _SC_SCHAR_MIN
5060 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5061#endif
5062#ifdef _SC_SELECT
5063 {"SC_SELECT", _SC_SELECT},
5064#endif
5065#ifdef _SC_SEMAPHORES
5066 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5067#endif
5068#ifdef _SC_SEM_NSEMS_MAX
5069 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5070#endif
5071#ifdef _SC_SEM_VALUE_MAX
5072 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5073#endif
5074#ifdef _SC_SHARED_MEMORY_OBJECTS
5075 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5076#endif
5077#ifdef _SC_SHRT_MAX
5078 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5079#endif
5080#ifdef _SC_SHRT_MIN
5081 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5082#endif
5083#ifdef _SC_SIGQUEUE_MAX
5084 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5085#endif
5086#ifdef _SC_SIGRT_MAX
5087 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5088#endif
5089#ifdef _SC_SIGRT_MIN
5090 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5091#endif
Fred Draked86ed291999-12-15 15:34:33 +00005092#ifdef _SC_SOFTPOWER
5093 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5094#endif
Fred Drakec9680921999-12-13 16:37:25 +00005095#ifdef _SC_SPLIT_CACHE
5096 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5097#endif
5098#ifdef _SC_SSIZE_MAX
5099 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5100#endif
5101#ifdef _SC_STACK_PROT
5102 {"SC_STACK_PROT", _SC_STACK_PROT},
5103#endif
5104#ifdef _SC_STREAM_MAX
5105 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5106#endif
5107#ifdef _SC_SYNCHRONIZED_IO
5108 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5109#endif
5110#ifdef _SC_THREADS
5111 {"SC_THREADS", _SC_THREADS},
5112#endif
5113#ifdef _SC_THREAD_ATTR_STACKADDR
5114 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5115#endif
5116#ifdef _SC_THREAD_ATTR_STACKSIZE
5117 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5118#endif
5119#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5120 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5121#endif
5122#ifdef _SC_THREAD_KEYS_MAX
5123 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5124#endif
5125#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5126 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5127#endif
5128#ifdef _SC_THREAD_PRIO_INHERIT
5129 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5130#endif
5131#ifdef _SC_THREAD_PRIO_PROTECT
5132 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5133#endif
5134#ifdef _SC_THREAD_PROCESS_SHARED
5135 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5136#endif
5137#ifdef _SC_THREAD_SAFE_FUNCTIONS
5138 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5139#endif
5140#ifdef _SC_THREAD_STACK_MIN
5141 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5142#endif
5143#ifdef _SC_THREAD_THREADS_MAX
5144 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5145#endif
5146#ifdef _SC_TIMERS
5147 {"SC_TIMERS", _SC_TIMERS},
5148#endif
5149#ifdef _SC_TIMER_MAX
5150 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5151#endif
5152#ifdef _SC_TTY_NAME_MAX
5153 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5154#endif
5155#ifdef _SC_TZNAME_MAX
5156 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5157#endif
5158#ifdef _SC_T_IOV_MAX
5159 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5160#endif
5161#ifdef _SC_UCHAR_MAX
5162 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5163#endif
5164#ifdef _SC_UINT_MAX
5165 {"SC_UINT_MAX", _SC_UINT_MAX},
5166#endif
5167#ifdef _SC_UIO_MAXIOV
5168 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5169#endif
5170#ifdef _SC_ULONG_MAX
5171 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5172#endif
5173#ifdef _SC_USHRT_MAX
5174 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5175#endif
5176#ifdef _SC_VERSION
5177 {"SC_VERSION", _SC_VERSION},
5178#endif
5179#ifdef _SC_WORD_BIT
5180 {"SC_WORD_BIT", _SC_WORD_BIT},
5181#endif
5182#ifdef _SC_XBS5_ILP32_OFF32
5183 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5184#endif
5185#ifdef _SC_XBS5_ILP32_OFFBIG
5186 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5187#endif
5188#ifdef _SC_XBS5_LP64_OFF64
5189 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5190#endif
5191#ifdef _SC_XBS5_LPBIG_OFFBIG
5192 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5193#endif
5194#ifdef _SC_XOPEN_CRYPT
5195 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5196#endif
5197#ifdef _SC_XOPEN_ENH_I18N
5198 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5199#endif
5200#ifdef _SC_XOPEN_LEGACY
5201 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5202#endif
5203#ifdef _SC_XOPEN_REALTIME
5204 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5205#endif
5206#ifdef _SC_XOPEN_REALTIME_THREADS
5207 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5208#endif
5209#ifdef _SC_XOPEN_SHM
5210 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5211#endif
5212#ifdef _SC_XOPEN_UNIX
5213 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5214#endif
5215#ifdef _SC_XOPEN_VERSION
5216 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5217#endif
5218#ifdef _SC_XOPEN_XCU_VERSION
5219 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5220#endif
5221#ifdef _SC_XOPEN_XPG2
5222 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5223#endif
5224#ifdef _SC_XOPEN_XPG3
5225 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5226#endif
5227#ifdef _SC_XOPEN_XPG4
5228 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5229#endif
5230};
5231
5232static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005233conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005234{
5235 return conv_confname(arg, valuep, posix_constants_sysconf,
5236 sizeof(posix_constants_sysconf)
5237 / sizeof(struct constdef));
5238}
5239
5240static char posix_sysconf__doc__[] = "\
5241sysconf(name) -> integer\n\
5242Return an integer-valued system configuration variable.";
5243
5244static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005245posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005246{
5247 PyObject *result = NULL;
5248 int name;
5249
5250 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5251 int value;
5252
5253 errno = 0;
5254 value = sysconf(name);
5255 if (value == -1 && errno != 0)
5256 posix_error();
5257 else
5258 result = PyInt_FromLong(value);
5259 }
5260 return result;
5261}
5262#endif
5263
5264
Fred Drakebec628d1999-12-15 18:31:10 +00005265/* This code is used to ensure that the tables of configuration value names
5266 * are in sorted order as required by conv_confname(), and also to build the
5267 * the exported dictionaries that are used to publish information about the
5268 * names available on the host platform.
5269 *
5270 * Sorting the table at runtime ensures that the table is properly ordered
5271 * when used, even for platforms we're not able to test on. It also makes
5272 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005273 */
Fred Drakebec628d1999-12-15 18:31:10 +00005274
5275static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005276cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005277{
5278 const struct constdef *c1 =
5279 (const struct constdef *) v1;
5280 const struct constdef *c2 =
5281 (const struct constdef *) v2;
5282
5283 return strcmp(c1->name, c2->name);
5284}
5285
5286static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005287setup_confname_table(struct constdef *table, size_t tablesize,
5288 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005289{
Fred Drakebec628d1999-12-15 18:31:10 +00005290 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005291 size_t i;
5292 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005293
5294 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5295 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005296 if (d == NULL)
5297 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005298
Barry Warsaw3155db32000-04-13 15:20:40 +00005299 for (i=0; i < tablesize; ++i) {
5300 PyObject *o = PyInt_FromLong(table[i].value);
5301 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5302 Py_XDECREF(o);
5303 Py_DECREF(d);
5304 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005305 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005306 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005307 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005308 status = PyDict_SetItemString(moddict, tablename, d);
5309 Py_DECREF(d);
5310 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005311}
5312
Fred Drakebec628d1999-12-15 18:31:10 +00005313/* Return -1 on failure, 0 on success. */
5314static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005315setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005316{
5317#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005318 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005319 sizeof(posix_constants_pathconf)
5320 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005321 "pathconf_names", moddict))
5322 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005323#endif
5324#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005325 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005326 sizeof(posix_constants_confstr)
5327 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005328 "confstr_names", moddict))
5329 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005330#endif
5331#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005332 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005333 sizeof(posix_constants_sysconf)
5334 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005335 "sysconf_names", moddict))
5336 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005337#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005338 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005339}
Fred Draked86ed291999-12-15 15:34:33 +00005340
5341
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005342static char posix_abort__doc__[] = "\
5343abort() -> does not return!\n\
5344Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5345in the hardest way possible on the hosting operating system.";
5346
5347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005348posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005349{
5350 if (!PyArg_ParseTuple(args, ":abort"))
5351 return NULL;
5352 abort();
5353 /*NOTREACHED*/
5354 Py_FatalError("abort() called from Python code didn't abort!");
5355 return NULL;
5356}
Fred Drakebec628d1999-12-15 18:31:10 +00005357
Tim Petersf58a7aa2000-09-22 10:05:54 +00005358#ifdef MS_WIN32
5359static char win32_startfile__doc__[] = "\
5360startfile(filepath) - Start a file with its associated application.\n\
5361\n\
5362This acts like double-clicking the file in Explorer, or giving the file\n\
5363name as an argument to the DOS \"start\" command: the file is opened\n\
5364with whatever application (if any) its extension is associated.\n\
5365\n\
5366startfile returns as soon as the associated application is launched.\n\
5367There is no option to wait for the application to close, and no way\n\
5368to retrieve the application's exit status.\n\
5369\n\
5370The filepath is relative to the current directory. If you want to use\n\
5371an absolute path, make sure the first character is not a slash (\"/\");\n\
5372the underlying Win32 ShellExecute function doesn't work if it is.";
5373
5374static PyObject *
5375win32_startfile(PyObject *self, PyObject *args)
5376{
5377 char *filepath;
5378 HINSTANCE rc;
5379 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5380 return NULL;
5381 Py_BEGIN_ALLOW_THREADS
5382 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5383 Py_END_ALLOW_THREADS
5384 if (rc <= (HINSTANCE)32)
5385 return win32_error("startfile", filepath);
5386 Py_INCREF(Py_None);
5387 return Py_None;
5388}
5389#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005390
5391static PyMethodDef posix_methods[] = {
5392 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5393#ifdef HAVE_TTYNAME
5394 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5395#endif
5396 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5397 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005398#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005399 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005400#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005401#ifdef HAVE_CHROOT
5402 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5403#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005404#ifdef HAVE_CTERMID
5405 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5406#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005407#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005408 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005409#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005410#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005411 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005412#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005413 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5414 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5415 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005416#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005417 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005418#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005419#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005420 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005421#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005422 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5423 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5424 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005425#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005426 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005427#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005428#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005429 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005430#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005431 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005432#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005433 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005434#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005435 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5436 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5437 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005438#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005439 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005440#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005441 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005442#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005443 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5444 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005445#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005446#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005447 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5448 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005449#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005450#ifdef HAVE_FORK1
5451 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5452#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005453#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005454 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005455#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005456#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005457 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005458#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005459#ifdef HAVE_FORKPTY
5460 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5461#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005462#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005463 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005464#endif /* HAVE_GETEGID */
5465#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005466 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005467#endif /* HAVE_GETEUID */
5468#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005469 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005470#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005471#ifdef HAVE_GETGROUPS
5472 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5473#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005474 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005475#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005476 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005477#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005478#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005479 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005480#endif /* HAVE_GETPPID */
5481#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005482 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005483#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005484#ifdef HAVE_GETLOGIN
5485 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5486#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005487#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005488 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005489#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005490#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005491 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005492#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005493#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005494 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005495#ifdef MS_WIN32
5496 {"popen2", win32_popen2, METH_VARARGS},
5497 {"popen3", win32_popen3, METH_VARARGS},
5498 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005499 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005500#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005501#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005502#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005503 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005504#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005505#ifdef HAVE_SETEUID
5506 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5507#endif /* HAVE_SETEUID */
5508#ifdef HAVE_SETEGID
5509 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5510#endif /* HAVE_SETEGID */
5511#ifdef HAVE_SETREUID
5512 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5513#endif /* HAVE_SETREUID */
5514#ifdef HAVE_SETREGID
5515 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5516#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005517#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005518 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005519#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005520#ifdef HAVE_SETGROUPS
5521 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5522#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005523#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005524 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005525#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005526#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005527 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005528#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005529#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005530 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005531#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005532#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005533 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005534#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005535#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005536 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005537#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005538#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005539 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005540#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005541#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005542 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005543#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005544 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5545 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5546 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5547 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5548 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5549 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5550 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5551 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5552 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005553 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005554#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005555 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005556#endif
5557#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005558 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005559#endif
5560#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005561 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005562#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005563#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005564 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005565#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005566#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005567 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005568#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005569#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005570 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005571#endif
5572#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005573 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005574#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005575#ifdef HAVE_SYS_WAIT_H
5576#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005577 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005578#endif /* WIFSTOPPED */
5579#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005580 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005581#endif /* WIFSIGNALED */
5582#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005583 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005584#endif /* WIFEXITED */
5585#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005586 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005587#endif /* WEXITSTATUS */
5588#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005589 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005590#endif /* WTERMSIG */
5591#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005592 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005593#endif /* WSTOPSIG */
5594#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005595#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005596 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005597#endif
5598#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005599 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005600#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005601#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005602 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5603#endif
5604#ifdef HAVE_TEMPNAM
5605 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5606#endif
5607#ifdef HAVE_TMPNAM
5608 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5609#endif
Fred Drakec9680921999-12-13 16:37:25 +00005610#ifdef HAVE_CONFSTR
5611 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5612#endif
5613#ifdef HAVE_SYSCONF
5614 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5615#endif
5616#ifdef HAVE_FPATHCONF
5617 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5618#endif
5619#ifdef HAVE_PATHCONF
5620 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5621#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005622 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005623#ifdef MS_WIN32
5624 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5625#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005626 {NULL, NULL} /* Sentinel */
5627};
5628
5629
Barry Warsaw4a342091996-12-19 23:50:02 +00005630static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005631ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005632{
5633 PyObject* v = PyInt_FromLong(value);
5634 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5635 return -1; /* triggers fatal error */
5636
5637 Py_DECREF(v);
5638 return 0;
5639}
5640
Guido van Rossumd48f2521997-12-05 22:19:34 +00005641#if defined(PYOS_OS2)
5642/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5643static int insertvalues(PyObject *d)
5644{
5645 APIRET rc;
5646 ULONG values[QSV_MAX+1];
5647 PyObject *v;
5648 char *ver, tmp[10];
5649
5650 Py_BEGIN_ALLOW_THREADS
5651 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5652 Py_END_ALLOW_THREADS
5653
5654 if (rc != NO_ERROR) {
5655 os2_error(rc);
5656 return -1;
5657 }
5658
5659 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5660 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5661 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5662 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5663 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5664 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5665 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5666
5667 switch (values[QSV_VERSION_MINOR]) {
5668 case 0: ver = "2.00"; break;
5669 case 10: ver = "2.10"; break;
5670 case 11: ver = "2.11"; break;
5671 case 30: ver = "3.00"; break;
5672 case 40: ver = "4.00"; break;
5673 case 50: ver = "5.00"; break;
5674 default:
5675 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5676 values[QSV_VERSION_MINOR]);
5677 ver = &tmp[0];
5678 }
5679
5680 /* Add Indicator of the Version of the Operating System */
5681 v = PyString_FromString(ver);
5682 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5683 return -1;
5684 Py_DECREF(v);
5685
5686 /* Add Indicator of Which Drive was Used to Boot the System */
5687 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5688 tmp[1] = ':';
5689 tmp[2] = '\0';
5690
5691 v = PyString_FromString(tmp);
5692 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5693 return -1;
5694 Py_DECREF(v);
5695
5696 return 0;
5697}
5698#endif
5699
Barry Warsaw4a342091996-12-19 23:50:02 +00005700static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005701all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005702{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005703#ifdef F_OK
5704 if (ins(d, "F_OK", (long)F_OK)) return -1;
5705#endif
5706#ifdef R_OK
5707 if (ins(d, "R_OK", (long)R_OK)) return -1;
5708#endif
5709#ifdef W_OK
5710 if (ins(d, "W_OK", (long)W_OK)) return -1;
5711#endif
5712#ifdef X_OK
5713 if (ins(d, "X_OK", (long)X_OK)) return -1;
5714#endif
Fred Drakec9680921999-12-13 16:37:25 +00005715#ifdef NGROUPS_MAX
5716 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5717#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005718#ifdef TMP_MAX
5719 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5720#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005721#ifdef WNOHANG
5722 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5723#endif
5724#ifdef O_RDONLY
5725 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5726#endif
5727#ifdef O_WRONLY
5728 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5729#endif
5730#ifdef O_RDWR
5731 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5732#endif
5733#ifdef O_NDELAY
5734 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5735#endif
5736#ifdef O_NONBLOCK
5737 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5738#endif
5739#ifdef O_APPEND
5740 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5741#endif
5742#ifdef O_DSYNC
5743 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5744#endif
5745#ifdef O_RSYNC
5746 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5747#endif
5748#ifdef O_SYNC
5749 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5750#endif
5751#ifdef O_NOCTTY
5752 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5753#endif
5754#ifdef O_CREAT
5755 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5756#endif
5757#ifdef O_EXCL
5758 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5759#endif
5760#ifdef O_TRUNC
5761 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5762#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005763#ifdef O_BINARY
5764 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5765#endif
5766#ifdef O_TEXT
5767 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5768#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005769
Guido van Rossum246bc171999-02-01 23:54:31 +00005770#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005771 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5772 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5773 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5774 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5775 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005776#endif
5777
Guido van Rossumd48f2521997-12-05 22:19:34 +00005778#if defined(PYOS_OS2)
5779 if (insertvalues(d)) return -1;
5780#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005781 return 0;
5782}
5783
5784
Tim Peters58e0a8c2001-05-14 22:32:33 +00005785#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005786#define INITFUNC initnt
5787#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005788
5789#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005790#define INITFUNC initos2
5791#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005792
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005793#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005794#define INITFUNC initposix
5795#define MODNAME "posix"
5796#endif
5797
Guido van Rossum3886bb61998-12-04 18:50:17 +00005798DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005799INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005800{
Barry Warsaw53699e91996-12-10 23:23:01 +00005801 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005802
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005803 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005804 posix_methods,
5805 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005806 (PyObject *)NULL,
5807 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005808 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005809
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005810 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005811 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005812 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005813 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005814 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005815
Barry Warsaw4a342091996-12-19 23:50:02 +00005816 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005817 return;
5818
Fred Drakebec628d1999-12-15 18:31:10 +00005819 if (setup_confname_tables(d))
5820 return;
5821
Barry Warsawca74da41999-02-09 19:31:45 +00005822 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005823
Guido van Rossumb3d39562000-01-31 18:41:26 +00005824#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005825 if (posix_putenv_garbage == NULL)
5826 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005827#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005828}