blob: d7d7c3ffb4c3410573691b8d5f2681e837717242 [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 Rossum98bf58f2001-10-18 20:34:25 +000020#include "structseq.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000021
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000022#if defined(PYOS_OS2)
23#define INCL_DOS
24#define INCL_DOSERRORS
25#define INCL_DOSPROCESS
26#define INCL_NOPMAPI
27#include <os2.h>
28#endif
29
Guido van Rossumb6775db1994-08-01 11:34:53 +000030#include <sys/types.h>
31#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000032
Guido van Rossum36bc6801995-06-14 22:54:23 +000033#ifdef HAVE_SYS_WAIT_H
34#include <sys/wait.h> /* For WNOHANG */
35#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000036
Guido van Rossuma376cc51996-12-05 23:43:35 +000037#ifdef HAVE_SIGNAL_H
38#include <signal.h>
39#endif
40
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#ifdef HAVE_FCNTL_H
42#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000043#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000044
Guido van Rossuma6535fd2001-10-18 19:44:10 +000045#ifdef HAVE_GRP_H
46#include <grp.h>
47#endif
48
Skip Montanaro8216c182001-02-27 17:04:34 +000049/* pick up declaration of confstr on some systems? */
50#ifdef HAVE_UNISTD_H
51#include <unistd.h>
52#endif /* HAVE_UNISTD_H */
53
Guido van Rossuma4916fa1996-05-23 22:58:55 +000054/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000055/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000056#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000057#include <process.h>
58#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000059#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000060#define HAVE_GETCWD 1
61#define HAVE_OPENDIR 1
62#define HAVE_SYSTEM 1
63#if defined(__OS2__)
64#define HAVE_EXECV 1
65#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000066#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000067#include <process.h>
68#else
69#ifdef __BORLANDC__ /* Borland compiler */
70#define HAVE_EXECV 1
71#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072#define HAVE_OPENDIR 1
73#define HAVE_PIPE 1
74#define HAVE_POPEN 1
75#define HAVE_SYSTEM 1
76#define HAVE_WAIT 1
77#else
78#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000079#define HAVE_GETCWD 1
80#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000081#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#define HAVE_EXECV 1
83#define HAVE_PIPE 1
84#define HAVE_POPEN 1
85#define HAVE_SYSTEM 1
86#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000087#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#else /* all other compilers */
89/* Unix functions that the configure script doesn't check for */
90#define HAVE_EXECV 1
91#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000092#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
93#define HAVE_FORK1 1
94#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000095#define HAVE_GETCWD 1
96#define HAVE_GETEGID 1
97#define HAVE_GETEUID 1
98#define HAVE_GETGID 1
99#define HAVE_GETPPID 1
100#define HAVE_GETUID 1
101#define HAVE_KILL 1
102#define HAVE_OPENDIR 1
103#define HAVE_PIPE 1
104#define HAVE_POPEN 1
105#define HAVE_SYSTEM 1
106#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000107#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#endif /* _MSC_VER */
109#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000110#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000111#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000112
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000114
Guido van Rossumb6775db1994-08-01 11:34:53 +0000115#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000116#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000117#endif
118
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000119#if defined(sun) && !defined(__SVR4)
120/* SunOS 4.1.4 doesn't have prototypes for these: */
121extern int rename(const char *, const char *);
122extern int pclose(FILE *);
123extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000124extern int fsync(int);
125extern int lstat(const char *, struct stat *);
126extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000127#endif
128
Guido van Rossum36bc6801995-06-14 22:54:23 +0000129#ifdef NeXT
130/* NeXT's <unistd.h> and <utime.h> aren't worth much */
131#undef HAVE_UNISTD_H
132#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000133#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000134/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000135#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000136#endif
137
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000138#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000155#ifdef __BORLANDC__
156extern int chmod(const char *, int);
157#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000159#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int chown(const char *, uid_t, gid_t);
161extern char *getcwd(char *, int);
162extern char *strerror(int);
163extern int link(const char *, const char *);
164extern int rename(const char *, const char *);
165extern int stat(const char *, struct stat *);
166extern int unlink(const char *);
167extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000170#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000173#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000175
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178#ifdef HAVE_UTIME_H
179#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000182#ifdef HAVE_SYS_UTIME_H
183#include <sys/utime.h>
184#define HAVE_UTIME_H /* pretend we do for the rest of this file */
185#endif /* HAVE_SYS_UTIME_H */
186
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187#ifdef HAVE_SYS_TIMES_H
188#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_PARAM_H
192#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifdef HAVE_SYS_UTSNAME_H
196#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
199#ifndef MAXPATHLEN
200#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000201#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000203#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000207#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000208#include <direct.h>
209#define NAMLEN(dirent) strlen((dirent)->d_name)
210#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000214#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000216#endif
217#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000219#endif
220#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000222#endif
223#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <direct.h>
227#include <io.h>
228#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000229#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000231#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000233#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#else /* 16-bit Windows */
235#include <dos.h>
236#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000237#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
Guido van Rossumd48f2521997-12-05 22:19:34 +0000240#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000242#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000244#ifdef UNION_WAIT
245/* Emulate some macros on systems that have a union instead of macros */
246
247#ifndef WIFEXITED
248#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
249#endif
250
251#ifndef WEXITSTATUS
252#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
253#endif
254
255#ifndef WTERMSIG
256#define WTERMSIG(u_wait) ((u_wait).w_termsig)
257#endif
258
259#endif /* UNION_WAIT */
260
Greg Wardb48bc172000-03-01 21:51:56 +0000261/* Don't use the "_r" form if we don't need it (also, won't have a
262 prototype for it, at least on Solaris -- maybe others as well?). */
263#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
264#define USE_CTERMID_R
265#endif
266
267#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
268#define USE_TMPNAM_R
269#endif
270
Fred Drake699f3522000-06-29 21:12:41 +0000271/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000272#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000273#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000274# define STAT _stati64
275# define FSTAT _fstati64
276# define STRUCT_STAT struct _stati64
277#else
278# define STAT stat
279# define FSTAT fstat
280# define STRUCT_STAT struct stat
281#endif
282
283
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284/* Return a dictionary corresponding to the POSIX environment table */
285
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000286#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289
Barry Warsaw53699e91996-12-10 23:23:01 +0000290static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000291convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292{
Barry Warsaw53699e91996-12-10 23:23:01 +0000293 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000295 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296 if (d == NULL)
297 return NULL;
298 if (environ == NULL)
299 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000300 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000302 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000303 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 char *p = strchr(*e, '=');
305 if (p == NULL)
306 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000307 k = PyString_FromStringAndSize(*e, (int)(p-*e));
308 if (k == NULL) {
309 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000311 }
312 v = PyString_FromString(p+1);
313 if (v == NULL) {
314 PyErr_Clear();
315 Py_DECREF(k);
316 continue;
317 }
318 if (PyDict_GetItem(d, k) == NULL) {
319 if (PyDict_SetItem(d, k, v) != 0)
320 PyErr_Clear();
321 }
322 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000323 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000325#if defined(PYOS_OS2)
326 {
327 APIRET rc;
328 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
329
330 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000331 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000332 PyObject *v = PyString_FromString(buffer);
333 PyDict_SetItemString(d, "BEGINLIBPATH", v);
334 Py_DECREF(v);
335 }
336 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
337 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
338 PyObject *v = PyString_FromString(buffer);
339 PyDict_SetItemString(d, "ENDLIBPATH", v);
340 Py_DECREF(v);
341 }
342 }
343#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344 return d;
345}
346
347
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348/* Set a POSIX-specific error from errno, and return NULL */
349
Barry Warsawd58d7641998-07-23 16:14:40 +0000350static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000351posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000352{
Barry Warsawca74da41999-02-09 19:31:45 +0000353 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354}
Barry Warsawd58d7641998-07-23 16:14:40 +0000355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000356posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000357{
Barry Warsawca74da41999-02-09 19:31:45 +0000358 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000359}
360
Mark Hammondef8b6542001-05-13 08:04:26 +0000361static PyObject *
362posix_error_with_allocated_filename(char* name)
363{
364 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
365 PyMem_Free(name);
366 return rc;
367}
368
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000369#ifdef MS_WIN32
370static PyObject *
371win32_error(char* function, char* filename)
372{
Mark Hammond33a6da92000-08-15 00:46:38 +0000373 /* XXX We should pass the function name along in the future.
374 (_winreg.c also wants to pass the function name.)
375 This would however require an additional param to the
376 Windows error object, which is non-trivial.
377 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000378 errno = GetLastError();
379 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000380 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000381 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000382 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000383}
384#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385
Guido van Rossumd48f2521997-12-05 22:19:34 +0000386#if defined(PYOS_OS2)
387/**********************************************************************
388 * Helper Function to Trim and Format OS/2 Messages
389 **********************************************************************/
390 static void
391os2_formatmsg(char *msgbuf, int msglen, char *reason)
392{
393 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
394
395 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
396 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
397
398 while (lastc > msgbuf && isspace(*lastc))
399 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
400 }
401
402 /* Add Optional Reason Text */
403 if (reason) {
404 strcat(msgbuf, " : ");
405 strcat(msgbuf, reason);
406 }
407}
408
409/**********************************************************************
410 * Decode an OS/2 Operating System Error Code
411 *
412 * A convenience function to lookup an OS/2 error code and return a
413 * text message we can use to raise a Python exception.
414 *
415 * Notes:
416 * The messages for errors returned from the OS/2 kernel reside in
417 * the file OSO001.MSG in the \OS2 directory hierarchy.
418 *
419 **********************************************************************/
420 static char *
421os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
422{
423 APIRET rc;
424 ULONG msglen;
425
426 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
427 Py_BEGIN_ALLOW_THREADS
428 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
429 errorcode, "oso001.msg", &msglen);
430 Py_END_ALLOW_THREADS
431
432 if (rc == NO_ERROR)
433 os2_formatmsg(msgbuf, msglen, reason);
434 else
435 sprintf(msgbuf, "unknown OS error #%d", errorcode);
436
437 return msgbuf;
438}
439
440/* Set an OS/2-specific error and return NULL. OS/2 kernel
441 errors are not in a global variable e.g. 'errno' nor are
442 they congruent with posix error numbers. */
443
444static PyObject * os2_error(int code)
445{
446 char text[1024];
447 PyObject *v;
448
449 os2_strerror(text, sizeof(text), code, "");
450
451 v = Py_BuildValue("(is)", code, text);
452 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000453 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000454 Py_DECREF(v);
455 }
456 return NULL; /* Signal to Python that an Exception is Pending */
457}
458
459#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000460
461/* POSIX generic methods */
462
Barry Warsaw53699e91996-12-10 23:23:01 +0000463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000464posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000465{
466 int fd;
467 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000468 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000469 return NULL;
470 Py_BEGIN_ALLOW_THREADS
471 res = (*func)(fd);
472 Py_END_ALLOW_THREADS
473 if (res < 0)
474 return posix_error();
475 Py_INCREF(Py_None);
476 return Py_None;
477}
478
479
480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000481posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482{
Mark Hammondef8b6542001-05-13 08:04:26 +0000483 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000484 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000485 if (!PyArg_ParseTuple(args, format,
486 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000488 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000489 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000490 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000491 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000492 return posix_error_with_allocated_filename(path1);
493 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000494 Py_INCREF(Py_None);
495 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000496}
497
Barry Warsaw53699e91996-12-10 23:23:01 +0000498static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000499posix_2str(PyObject *args, char *format,
500 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501{
Mark Hammondef8b6542001-05-13 08:04:26 +0000502 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000503 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000504 if (!PyArg_ParseTuple(args, format,
505 Py_FileSystemDefaultEncoding, &path1,
506 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000507 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000508 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000509 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000510 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000511 PyMem_Free(path1);
512 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000513 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000514 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000515 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000516 Py_INCREF(Py_None);
517 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000518}
519
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000520static char stat_result__doc__[] =
521"stat_result: Result from stat or lstat.\n\n\
522This object may be accessed either as a tuple of\n\
523 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
524or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
525\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000526Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000527they are available as attributes only.\n\
528\n\
529See os.stat for more information.\n";
530
531static PyStructSequence_Field stat_result_fields[] = {
532 {"st_mode", "protection bits"},
533 {"st_ino", "inode"},
534 {"st_dev", "device"},
535 {"st_nlink", "number of hard links"},
536 {"st_uid", "user ID of owner"},
537 {"st_gid", "group ID of owner"},
538 {"st_size", "total size, in bytes"},
539 {"st_atime", "time of last access"},
540 {"st_mtime", "time of last modification"},
541 {"st_ctime", "time of last change"},
542#ifdef HAVE_ST_BLKSIZE
543 {"st_blksize", "blocksize for filesystem I/O"},
544#endif
545#ifdef HAVE_ST_BLOCKS
546 {"st_blocks", "number of blocks allocated"},
547#endif
548#ifdef HAVE_ST_RDEV
549 {"st_rdev", "device type (if inode device)"},
550#endif
551 {0}
552};
553
554#ifdef HAVE_ST_BLKSIZE
555#define ST_BLKSIZE_IDX 10
556#else
557#define ST_BLKSIZE_IDX 9
558#endif
559
560#ifdef HAVE_ST_BLOCKS
561#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
562#else
563#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
564#endif
565
566#ifdef HAVE_ST_RDEV
567#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
568#else
569#define ST_RDEV_IDX ST_BLOCKS_IDX
570#endif
571
572static PyStructSequence_Desc stat_result_desc = {
573 "stat_result", /* name */
574 stat_result__doc__, /* doc */
575 stat_result_fields,
576 10
577};
578
579static char statvfs_result__doc__[] =
580"statvfs_result: Result from statvfs or fstatvfs.\n\n\
581This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000582 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
583or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000584\n\
585See os.statvfs for more information.\n";
586
587static PyStructSequence_Field statvfs_result_fields[] = {
588 {"f_bsize", },
589 {"f_frsize", },
590 {"f_blocks", },
591 {"f_bfree", },
592 {"f_bavail", },
593 {"f_files", },
594 {"f_ffree", },
595 {"f_favail", },
596 {"f_flag", },
597 {"f_namemax",},
598 {0}
599};
600
601static PyStructSequence_Desc statvfs_result_desc = {
602 "statvfs_result", /* name */
603 statvfs_result__doc__, /* doc */
604 statvfs_result_fields,
605 10
606};
607
608static PyTypeObject StatResultType;
609static PyTypeObject StatVFSResultType;
610
Fred Drake699f3522000-06-29 21:12:41 +0000611/* pack a system stat C structure into the Python stat tuple
612 (used by posix_stat() and posix_fstat()) */
613static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000614_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000615{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000616 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000617 if (v == NULL)
618 return NULL;
619
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000620 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000621#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000622 PyStructSequence_SET_ITEM(v, 1,
623 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000624#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000625 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000626#endif
627#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000628 PyStructSequence_SET_ITEM(v, 2,
629 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000630#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000631 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000632#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000633 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
634 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
635 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000636#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000637 PyStructSequence_SET_ITEM(v, 6,
638 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000639#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000640 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000641#endif
642#if SIZEOF_TIME_T > SIZEOF_LONG
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000643 PyStructSequence_SET_ITEM(v, 7,
644 PyLong_FromLongLong((LONG_LONG)st.st_atime));
645 PyStructSequence_SET_ITEM(v, 8,
646 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
647 PyStructSequence_SET_ITEM(v, 9,
648 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000649#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000650 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
651 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
652 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
653#endif
654
655#ifdef HAVE_ST_BLKSIZE
656 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
657 PyInt_FromLong((long)st.st_blksize));
658#endif
659#ifdef HAVE_ST_BLOCKS
660 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
661 PyInt_FromLong((long)st.st_blocks));
662#endif
663#ifdef HAVE_ST_RDEV
664 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
665 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000666#endif
667
668 if (PyErr_Occurred()) {
669 Py_DECREF(v);
670 return NULL;
671 }
672
673 return v;
674}
675
Barry Warsaw53699e91996-12-10 23:23:01 +0000676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000677posix_do_stat(PyObject *self, PyObject *args, char *format,
678 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000679{
Fred Drake699f3522000-06-29 21:12:41 +0000680 STRUCT_STAT st;
Mark Hammondef8b6542001-05-13 08:04:26 +0000681 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000682 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000683
684#ifdef MS_WIN32
685 int pathlen;
686 char pathcopy[MAX_PATH];
687#endif /* MS_WIN32 */
688
Mark Hammondef8b6542001-05-13 08:04:26 +0000689 if (!PyArg_ParseTuple(args, format,
690 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000692
693#ifdef MS_WIN32
694 pathlen = strlen(path);
695 /* the library call can blow up if the file name is too long! */
696 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000697 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000698 errno = ENAMETOOLONG;
699 return posix_error();
700 }
701
702 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000703 /* exception for specific or current drive root */
704 if (!((pathlen == 1) ||
705 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000706 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000707 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000708 {
709 strncpy(pathcopy, path, pathlen);
710 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
711 path = pathcopy;
712 }
713 }
714#endif /* MS_WIN32 */
715
Barry Warsaw53699e91996-12-10 23:23:01 +0000716 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000717 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000718 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000719 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000720 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000721
Mark Hammondef8b6542001-05-13 08:04:26 +0000722 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000723 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724}
725
726
727/* POSIX methods */
728
Guido van Rossum94f6f721999-01-06 18:42:14 +0000729static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000730"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000731Test for access to a file.";
732
733static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000734posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000735{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000736 char *path;
737 int mode;
738 int res;
739
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000740 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000741 return NULL;
742 Py_BEGIN_ALLOW_THREADS
743 res = access(path, mode);
744 Py_END_ALLOW_THREADS
745 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000746}
747
Guido van Rossumd371ff11999-01-25 16:12:23 +0000748#ifndef F_OK
749#define F_OK 0
750#endif
751#ifndef R_OK
752#define R_OK 4
753#endif
754#ifndef W_OK
755#define W_OK 2
756#endif
757#ifndef X_OK
758#define X_OK 1
759#endif
760
761#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000762static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000763"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000764Return the name of the terminal device connected to 'fd'.";
765
766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000767posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000768{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000769 int id;
770 char *ret;
771
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000772 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000773 return NULL;
774
Guido van Rossum94f6f721999-01-06 18:42:14 +0000775 ret = ttyname(id);
776 if (ret == NULL)
777 return(posix_error());
778 return(PyString_FromString(ret));
779}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000780#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000781
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000782#ifdef HAVE_CTERMID
783static char posix_ctermid__doc__[] =
784"ctermid() -> String\n\
785Return the name of the controlling terminal for this process.";
786
787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000788posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000789{
790 char *ret;
791 char buffer[L_ctermid];
792
793 if (!PyArg_ParseTuple(args, ":ctermid"))
794 return NULL;
795
Greg Wardb48bc172000-03-01 21:51:56 +0000796#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000797 ret = ctermid_r(buffer);
798#else
799 ret = ctermid(buffer);
800#endif
801 if (ret == NULL)
802 return(posix_error());
803 return(PyString_FromString(buffer));
804}
805#endif
806
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000807static char posix_chdir__doc__[] =
808"chdir(path) -> None\n\
809Change the current working directory to the specified path.";
810
Barry Warsaw53699e91996-12-10 23:23:01 +0000811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000812posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813{
Mark Hammondef8b6542001-05-13 08:04:26 +0000814 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000815}
816
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000817
818static char posix_chmod__doc__[] =
819"chmod(path, mode) -> None\n\
820Change the access permissions of a file.";
821
Barry Warsaw53699e91996-12-10 23:23:01 +0000822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000823posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824{
Mark Hammondef8b6542001-05-13 08:04:26 +0000825 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000826 int i;
827 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000828 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
829 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000830 return NULL;
831 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000832 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000833 Py_END_ALLOW_THREADS
834 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000835 return posix_error_with_allocated_filename(path);
836 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000837 Py_INCREF(Py_None);
838 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000839}
840
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000841
Martin v. Löwis244edc82001-10-04 22:44:26 +0000842#ifdef HAVE_CHROOT
843static char posix_chroot__doc__[] =
844"chroot(path) -> None\n\
845Change root directory to path.";
846
847static PyObject *
848posix_chroot(PyObject *self, PyObject *args)
849{
850 return posix_1str(args, "et:chroot", chroot);
851}
852#endif
853
Guido van Rossum21142a01999-01-08 21:05:37 +0000854#ifdef HAVE_FSYNC
855static char posix_fsync__doc__[] =
856"fsync(fildes) -> None\n\
857force write of file with filedescriptor to disk.";
858
859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000860posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000861{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000862 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000863}
864#endif /* HAVE_FSYNC */
865
866#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000867
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000868#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000869extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
870#endif
871
Guido van Rossum21142a01999-01-08 21:05:37 +0000872static char posix_fdatasync__doc__[] =
873"fdatasync(fildes) -> None\n\
874force write of file with filedescriptor to disk.\n\
875 does not force update of metadata.";
876
877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000878posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000879{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000880 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000881}
882#endif /* HAVE_FDATASYNC */
883
884
Fredrik Lundh10723342000-07-10 16:38:09 +0000885#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000886static char posix_chown__doc__[] =
887"chown(path, uid, gid) -> None\n\
888Change the owner and group id of path to the numeric uid and gid.";
889
Barry Warsaw53699e91996-12-10 23:23:01 +0000890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000891posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000892{
Mark Hammondef8b6542001-05-13 08:04:26 +0000893 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000894 int uid, gid;
895 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000896 if (!PyArg_ParseTuple(args, "etii:chown",
897 Py_FileSystemDefaultEncoding, &path,
898 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000899 return NULL;
900 Py_BEGIN_ALLOW_THREADS
901 res = chown(path, (uid_t) uid, (gid_t) gid);
902 Py_END_ALLOW_THREADS
903 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000904 return posix_error_with_allocated_filename(path);
905 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000906 Py_INCREF(Py_None);
907 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000908}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000909#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000911
Guido van Rossum36bc6801995-06-14 22:54:23 +0000912#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000913static char posix_getcwd__doc__[] =
914"getcwd() -> path\n\
915Return a string representing the current working directory.";
916
Barry Warsaw53699e91996-12-10 23:23:01 +0000917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000918posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000919{
920 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000921 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000922 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000923 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000924 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000925 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000926 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000927 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000928 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000929 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000931#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000933
Guido van Rossumb6775db1994-08-01 11:34:53 +0000934#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000935static char posix_link__doc__[] =
936"link(src, dst) -> None\n\
937Create a hard link to a file.";
938
Barry Warsaw53699e91996-12-10 23:23:01 +0000939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000940posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000941{
Mark Hammondef8b6542001-05-13 08:04:26 +0000942 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000943}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000944#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000946
947static char posix_listdir__doc__[] =
948"listdir(path) -> list_of_strings\n\
949Return a list containing the names of the entries in the directory.\n\
950\n\
951 path: path of directory to list\n\
952\n\
953The list is in arbitrary order. It does not include the special\n\
954entries '.' and '..' even if they are present in the directory.";
955
Barry Warsaw53699e91996-12-10 23:23:01 +0000956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000957posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000958{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000960 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000961#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000962
Barry Warsaw53699e91996-12-10 23:23:01 +0000963 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000964 HANDLE hFindFile;
965 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000966 /* MAX_PATH characters could mean a bigger encoded string */
967 char namebuf[MAX_PATH*2+5];
968 char *bufptr = namebuf;
969 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000970 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000971
Mark Hammondef8b6542001-05-13 08:04:26 +0000972 if (!PyArg_ParseTuple(args, "et#:listdir",
973 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000974 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000975 ch = namebuf[len-1];
976 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000977 namebuf[len++] = '/';
978 strcpy(namebuf + len, "*.*");
979
Barry Warsaw53699e91996-12-10 23:23:01 +0000980 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000981 return NULL;
982
983 hFindFile = FindFirstFile(namebuf, &FileData);
984 if (hFindFile == INVALID_HANDLE_VALUE) {
985 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000986 if (errno == ERROR_FILE_NOT_FOUND)
987 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000988 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000989 }
990 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000991 if (FileData.cFileName[0] == '.' &&
992 (FileData.cFileName[1] == '\0' ||
993 FileData.cFileName[1] == '.' &&
994 FileData.cFileName[2] == '\0'))
995 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000996 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000997 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000998 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000999 d = NULL;
1000 break;
1001 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001002 if (PyList_Append(d, v) != 0) {
1003 Py_DECREF(v);
1004 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001005 d = NULL;
1006 break;
1007 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001008 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001009 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1010
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001011 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001012 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001013
1014 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001015
Tim Peters0bb44a42000-09-15 07:44:49 +00001016#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001017
1018#ifndef MAX_PATH
1019#define MAX_PATH 250
1020#endif
1021 char *name, *pt;
1022 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001023 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001024 char namebuf[MAX_PATH+5];
1025 struct _find_t ep;
1026
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001027 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001028 return NULL;
1029 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001030 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001031 return NULL;
1032 }
1033 strcpy(namebuf, name);
1034 for (pt = namebuf; *pt; pt++)
1035 if (*pt == '/')
1036 *pt = '\\';
1037 if (namebuf[len-1] != '\\')
1038 namebuf[len++] = '\\';
1039 strcpy(namebuf + len, "*.*");
1040
Barry Warsaw53699e91996-12-10 23:23:01 +00001041 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001042 return NULL;
1043
1044 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001045 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1046 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001047 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001048 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001049 }
1050 do {
1051 if (ep.name[0] == '.' &&
1052 (ep.name[1] == '\0' ||
1053 ep.name[1] == '.' &&
1054 ep.name[2] == '\0'))
1055 continue;
1056 strcpy(namebuf, ep.name);
1057 for (pt = namebuf; *pt; pt++)
1058 if (isupper(*pt))
1059 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001060 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001061 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001062 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001063 d = NULL;
1064 break;
1065 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001066 if (PyList_Append(d, v) != 0) {
1067 Py_DECREF(v);
1068 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001069 d = NULL;
1070 break;
1071 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001072 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001073 } while (_dos_findnext(&ep) == 0);
1074
1075 return d;
1076
Tim Peters0bb44a42000-09-15 07:44:49 +00001077#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001078
1079#ifndef MAX_PATH
1080#define MAX_PATH CCHMAXPATH
1081#endif
1082 char *name, *pt;
1083 int len;
1084 PyObject *d, *v;
1085 char namebuf[MAX_PATH+5];
1086 HDIR hdir = 1;
1087 ULONG srchcnt = 1;
1088 FILEFINDBUF3 ep;
1089 APIRET rc;
1090
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001091 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001092 return NULL;
1093 if (len >= MAX_PATH) {
1094 PyErr_SetString(PyExc_ValueError, "path too long");
1095 return NULL;
1096 }
1097 strcpy(namebuf, name);
1098 for (pt = namebuf; *pt; pt++)
1099 if (*pt == '/')
1100 *pt = '\\';
1101 if (namebuf[len-1] != '\\')
1102 namebuf[len++] = '\\';
1103 strcpy(namebuf + len, "*.*");
1104
1105 if ((d = PyList_New(0)) == NULL)
1106 return NULL;
1107
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001108 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1109 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001110 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001111 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1112 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1113 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001114
1115 if (rc != NO_ERROR) {
1116 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001117 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001118 }
1119
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001120 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001121 do {
1122 if (ep.achName[0] == '.'
1123 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001124 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001125
1126 strcpy(namebuf, ep.achName);
1127
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001128 /* Leave Case of Name Alone -- In Native Form */
1129 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001130
1131 v = PyString_FromString(namebuf);
1132 if (v == NULL) {
1133 Py_DECREF(d);
1134 d = NULL;
1135 break;
1136 }
1137 if (PyList_Append(d, v) != 0) {
1138 Py_DECREF(v);
1139 Py_DECREF(d);
1140 d = NULL;
1141 break;
1142 }
1143 Py_DECREF(v);
1144 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1145 }
1146
1147 return d;
1148#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001149
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001150 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001151 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001152 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001153 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001154 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001156 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001157 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001158 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001159 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001160 closedir(dirp);
1161 return NULL;
1162 }
1163 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001164 if (ep->d_name[0] == '.' &&
1165 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001166 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001167 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001168 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001169 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001170 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171 d = NULL;
1172 break;
1173 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001174 if (PyList_Append(d, v) != 0) {
1175 Py_DECREF(v);
1176 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001177 d = NULL;
1178 break;
1179 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001180 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001181 }
1182 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001183
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001185
Tim Peters0bb44a42000-09-15 07:44:49 +00001186#endif /* which OS */
1187} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001188
Mark Hammondef8b6542001-05-13 08:04:26 +00001189#ifdef MS_WIN32
1190/* A helper function for abspath on win32 */
1191static PyObject *
1192posix__getfullpathname(PyObject *self, PyObject *args)
1193{
1194 /* assume encoded strings wont more than double no of chars */
1195 char inbuf[MAX_PATH*2];
1196 char *inbufp = inbuf;
1197 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1198 char outbuf[MAX_PATH*2];
1199 char *temp;
1200 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1201 Py_FileSystemDefaultEncoding, &inbufp,
1202 &insize))
1203 return NULL;
1204 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1205 outbuf, &temp))
1206 return win32_error("GetFullPathName", inbuf);
1207 return PyString_FromString(outbuf);
1208} /* end of posix__getfullpathname */
1209#endif /* MS_WIN32 */
1210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001211static char posix_mkdir__doc__[] =
1212"mkdir(path [, mode=0777]) -> None\n\
1213Create a directory.";
1214
Barry Warsaw53699e91996-12-10 23:23:01 +00001215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001216posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001217{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001218 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001219 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001220 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001221 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1222 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001223 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001224 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001225#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001226 res = mkdir(path);
1227#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001228 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001229#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001230 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001231 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001232 return posix_error_with_allocated_filename(path);
1233 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001234 Py_INCREF(Py_None);
1235 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001236}
1237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001238
Guido van Rossumb6775db1994-08-01 11:34:53 +00001239#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001240#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1241#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1242#include <sys/resource.h>
1243#endif
1244#endif
1245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001246static char posix_nice__doc__[] =
1247"nice(inc) -> new_priority\n\
1248Decrease the priority of process and return new priority.";
1249
Barry Warsaw53699e91996-12-10 23:23:01 +00001250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001251posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001252{
1253 int increment, value;
1254
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001255 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001256 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001257
1258 /* There are two flavours of 'nice': one that returns the new
1259 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001260 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1261 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001262
1263 If we are of the nice family that returns the new priority, we
1264 need to clear errno before the call, and check if errno is filled
1265 before calling posix_error() on a returnvalue of -1, because the
1266 -1 may be the actual new priority! */
1267
1268 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001269 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001270#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001271 if (value == 0)
1272 value = getpriority(PRIO_PROCESS, 0);
1273#endif
1274 if (value == -1 && errno != 0)
1275 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001276 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001277 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001278}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001279#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001281
1282static char posix_rename__doc__[] =
1283"rename(old, new) -> None\n\
1284Rename a file or directory.";
1285
Barry Warsaw53699e91996-12-10 23:23:01 +00001286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001287posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001288{
Mark Hammondef8b6542001-05-13 08:04:26 +00001289 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001290}
1291
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001292
1293static char posix_rmdir__doc__[] =
1294"rmdir(path) -> None\n\
1295Remove a directory.";
1296
Barry Warsaw53699e91996-12-10 23:23:01 +00001297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001298posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299{
Mark Hammondef8b6542001-05-13 08:04:26 +00001300 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301}
1302
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001303
1304static char posix_stat__doc__[] =
1305"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1306Perform a stat system call on the given path.";
1307
Barry Warsaw53699e91996-12-10 23:23:01 +00001308static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001309posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310{
Mark Hammondef8b6542001-05-13 08:04:26 +00001311 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312}
1313
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001314
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001315#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001316static char posix_system__doc__[] =
1317"system(command) -> exit_status\n\
1318Execute the command (a string) in a subshell.";
1319
Barry Warsaw53699e91996-12-10 23:23:01 +00001320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001321posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001322{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001323 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001324 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001325 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001327 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001328 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001329 Py_END_ALLOW_THREADS
1330 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001332#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001334
1335static char posix_umask__doc__[] =
1336"umask(new_mask) -> old_mask\n\
1337Set the current numeric umask and return the previous umask.";
1338
Barry Warsaw53699e91996-12-10 23:23:01 +00001339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001340posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341{
1342 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001343 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001345 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346 if (i < 0)
1347 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001348 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001349}
1350
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001351
1352static char posix_unlink__doc__[] =
1353"unlink(path) -> None\n\
1354Remove a file (same as remove(path)).";
1355
1356static char posix_remove__doc__[] =
1357"remove(path) -> None\n\
1358Remove a file (same as unlink(path)).";
1359
Barry Warsaw53699e91996-12-10 23:23:01 +00001360static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001361posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362{
Mark Hammondef8b6542001-05-13 08:04:26 +00001363 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364}
1365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001366
Guido van Rossumb6775db1994-08-01 11:34:53 +00001367#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001368static char posix_uname__doc__[] =
1369"uname() -> (sysname, nodename, release, version, machine)\n\
1370Return a tuple identifying the current operating system.";
1371
Barry Warsaw53699e91996-12-10 23:23:01 +00001372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001373posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001374{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001375 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001376 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001377 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001378 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001379 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001380 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001381 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001382 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001383 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001384 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001385 u.sysname,
1386 u.nodename,
1387 u.release,
1388 u.version,
1389 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001390}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001391#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001393
1394static char posix_utime__doc__[] =
1395"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001396utime(path, None) -> None\n\
1397Set the access and modified time of the file to the given values. If the\n\
1398second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001399
Barry Warsaw53699e91996-12-10 23:23:01 +00001400static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001401posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001402{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001403 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001404 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001405 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001406 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001407
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001408/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001409#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001410 struct utimbuf buf;
1411#define ATIME buf.actime
1412#define MTIME buf.modtime
1413#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001414#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001415 time_t buf[2];
1416#define ATIME buf[0]
1417#define MTIME buf[1]
1418#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001419#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001420
Barry Warsaw3cef8562000-05-01 16:17:24 +00001421 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001422 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001423 if (arg == Py_None) {
1424 /* optional time values not given */
1425 Py_BEGIN_ALLOW_THREADS
1426 res = utime(path, NULL);
1427 Py_END_ALLOW_THREADS
1428 }
1429 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1430 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001431 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001432 return NULL;
1433 }
1434 else {
1435 ATIME = atime;
1436 MTIME = mtime;
1437 Py_BEGIN_ALLOW_THREADS
1438 res = utime(path, UTIME_ARG);
1439 Py_END_ALLOW_THREADS
1440 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001441 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001442 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001443 Py_INCREF(Py_None);
1444 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001445#undef UTIME_ARG
1446#undef ATIME
1447#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001448}
1449
Guido van Rossum85e3b011991-06-03 12:42:10 +00001450
Guido van Rossum3b066191991-06-04 19:40:25 +00001451/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001452
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001453static char posix__exit__doc__[] =
1454"_exit(status)\n\
1455Exit to the system with specified status, without normal exit processing.";
1456
Barry Warsaw53699e91996-12-10 23:23:01 +00001457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001458posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001459{
1460 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001461 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001462 return NULL;
1463 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001464 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001465}
1466
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001467
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001468#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001469static char posix_execv__doc__[] =
1470"execv(path, args)\n\
1471Execute an executable path with arguments, replacing current process.\n\
1472\n\
1473 path: path of executable file\n\
1474 args: tuple or list of strings";
1475
Barry Warsaw53699e91996-12-10 23:23:01 +00001476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001477posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001478{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001479 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001480 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001481 char **argvlist;
1482 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001483 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001484
Guido van Rossum89b33251993-10-22 14:26:06 +00001485 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001486 argv is a list or tuple of strings. */
1487
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001488 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001489 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001490 if (PyList_Check(argv)) {
1491 argc = PyList_Size(argv);
1492 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001493 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001494 else if (PyTuple_Check(argv)) {
1495 argc = PyTuple_Size(argv);
1496 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001497 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001498 else {
Fred Drake661ea262000-10-24 19:57:45 +00001499 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001500 return NULL;
1501 }
1502
1503 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001504 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001505 return NULL;
1506 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001507
Barry Warsaw53699e91996-12-10 23:23:01 +00001508 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001509 if (argvlist == NULL)
1510 return NULL;
1511 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001512 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1513 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001514 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001515 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001516 return NULL;
1517
Guido van Rossum85e3b011991-06-03 12:42:10 +00001518 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001519 }
1520 argvlist[argc] = NULL;
1521
Guido van Rossumb6775db1994-08-01 11:34:53 +00001522#ifdef BAD_EXEC_PROTOTYPES
1523 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001524#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001525 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001526#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001527
Guido van Rossum85e3b011991-06-03 12:42:10 +00001528 /* If we get here it's definitely an error */
1529
Barry Warsaw53699e91996-12-10 23:23:01 +00001530 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001531 return posix_error();
1532}
1533
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001534
1535static char posix_execve__doc__[] =
1536"execve(path, args, env)\n\
1537Execute a path with arguments and environment, replacing current process.\n\
1538\n\
1539 path: path of executable file\n\
1540 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001541 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001542
Barry Warsaw53699e91996-12-10 23:23:01 +00001543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001544posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001545{
1546 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001547 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001548 char **argvlist;
1549 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001550 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001551 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001552 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001553
1554 /* execve has three arguments: (path, argv, env), where
1555 argv is a list or tuple of strings and env is a dictionary
1556 like posix.environ. */
1557
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001558 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001559 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001560 if (PyList_Check(argv)) {
1561 argc = PyList_Size(argv);
1562 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001563 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001564 else if (PyTuple_Check(argv)) {
1565 argc = PyTuple_Size(argv);
1566 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001567 }
1568 else {
Fred Drake661ea262000-10-24 19:57:45 +00001569 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001570 return NULL;
1571 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001572 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001573 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001574 return NULL;
1575 }
1576
Guido van Rossum50422b42000-04-26 20:34:28 +00001577 if (argc == 0) {
1578 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001579 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001580 return NULL;
1581 }
1582
Barry Warsaw53699e91996-12-10 23:23:01 +00001583 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001584 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001585 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001586 return NULL;
1587 }
1588 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001589 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001590 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001591 &argvlist[i]))
1592 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001593 goto fail_1;
1594 }
1595 }
1596 argvlist[argc] = NULL;
1597
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001598 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001599 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001600 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001601 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001602 goto fail_1;
1603 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001604 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001605 keys = PyMapping_Keys(env);
1606 vals = PyMapping_Values(env);
1607 if (!keys || !vals)
1608 goto fail_2;
1609
1610 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001611 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001612
1613 key = PyList_GetItem(keys, pos);
1614 val = PyList_GetItem(vals, pos);
1615 if (!key || !val)
1616 goto fail_2;
1617
Fred Drake661ea262000-10-24 19:57:45 +00001618 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1619 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001620 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001621 goto fail_2;
1622 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001623
1624#if defined(PYOS_OS2)
1625 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1626 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1627#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001628 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001629 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001630 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001631 goto fail_2;
1632 }
1633 sprintf(p, "%s=%s", k, v);
1634 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001635#if defined(PYOS_OS2)
1636 }
1637#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001638 }
1639 envlist[envc] = 0;
1640
Guido van Rossumb6775db1994-08-01 11:34:53 +00001641
1642#ifdef BAD_EXEC_PROTOTYPES
1643 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001644#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001645 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001646#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001647
1648 /* If we get here it's definitely an error */
1649
1650 (void) posix_error();
1651
1652 fail_2:
1653 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001654 PyMem_DEL(envlist[envc]);
1655 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001656 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001657 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001658 Py_XDECREF(vals);
1659 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001660 return NULL;
1661}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001662#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001664
Guido van Rossuma1065681999-01-25 23:20:23 +00001665#ifdef HAVE_SPAWNV
1666static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001667"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001668Execute an executable path with arguments, replacing current process.\n\
1669\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001670 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001671 path: path of executable file\n\
1672 args: tuple or list of strings";
1673
1674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001675posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001676{
1677 char *path;
1678 PyObject *argv;
1679 char **argvlist;
1680 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001681 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001682 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001683
1684 /* spawnv has three arguments: (mode, path, argv), where
1685 argv is a list or tuple of strings. */
1686
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001687 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001688 return NULL;
1689 if (PyList_Check(argv)) {
1690 argc = PyList_Size(argv);
1691 getitem = PyList_GetItem;
1692 }
1693 else if (PyTuple_Check(argv)) {
1694 argc = PyTuple_Size(argv);
1695 getitem = PyTuple_GetItem;
1696 }
1697 else {
Fred Drake661ea262000-10-24 19:57:45 +00001698 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001699 return NULL;
1700 }
1701
1702 argvlist = PyMem_NEW(char *, argc+1);
1703 if (argvlist == NULL)
1704 return NULL;
1705 for (i = 0; i < argc; i++) {
1706 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1707 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001708 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001709 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001710 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001711 }
1712 }
1713 argvlist[argc] = NULL;
1714
Guido van Rossum246bc171999-02-01 23:54:31 +00001715 if (mode == _OLD_P_OVERLAY)
1716 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001717 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001718
1719 PyMem_DEL(argvlist);
1720
Fred Drake699f3522000-06-29 21:12:41 +00001721 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001722 return posix_error();
1723 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001724#if SIZEOF_LONG == SIZEOF_VOID_P
1725 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001726#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001727 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001728#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001729}
1730
1731
1732static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001733"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001734Execute a path with arguments and environment, replacing current process.\n\
1735\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001736 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001737 path: path of executable file\n\
1738 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001739 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001740
1741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001742posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001743{
1744 char *path;
1745 PyObject *argv, *env;
1746 char **argvlist;
1747 char **envlist;
1748 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1749 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001750 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001751 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001752
1753 /* spawnve has four arguments: (mode, path, argv, env), where
1754 argv is a list or tuple of strings and env is a dictionary
1755 like posix.environ. */
1756
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001757 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001758 return NULL;
1759 if (PyList_Check(argv)) {
1760 argc = PyList_Size(argv);
1761 getitem = PyList_GetItem;
1762 }
1763 else if (PyTuple_Check(argv)) {
1764 argc = PyTuple_Size(argv);
1765 getitem = PyTuple_GetItem;
1766 }
1767 else {
Fred Drake661ea262000-10-24 19:57:45 +00001768 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001769 return NULL;
1770 }
1771 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001772 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001773 return NULL;
1774 }
1775
1776 argvlist = PyMem_NEW(char *, argc+1);
1777 if (argvlist == NULL) {
1778 PyErr_NoMemory();
1779 return NULL;
1780 }
1781 for (i = 0; i < argc; i++) {
1782 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001783 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001784 &argvlist[i]))
1785 {
1786 goto fail_1;
1787 }
1788 }
1789 argvlist[argc] = NULL;
1790
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001791 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001792 envlist = PyMem_NEW(char *, i + 1);
1793 if (envlist == NULL) {
1794 PyErr_NoMemory();
1795 goto fail_1;
1796 }
1797 envc = 0;
1798 keys = PyMapping_Keys(env);
1799 vals = PyMapping_Values(env);
1800 if (!keys || !vals)
1801 goto fail_2;
1802
1803 for (pos = 0; pos < i; pos++) {
1804 char *p, *k, *v;
1805
1806 key = PyList_GetItem(keys, pos);
1807 val = PyList_GetItem(vals, pos);
1808 if (!key || !val)
1809 goto fail_2;
1810
Fred Drake661ea262000-10-24 19:57:45 +00001811 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1812 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001813 {
1814 goto fail_2;
1815 }
1816 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1817 if (p == NULL) {
1818 PyErr_NoMemory();
1819 goto fail_2;
1820 }
1821 sprintf(p, "%s=%s", k, v);
1822 envlist[envc++] = p;
1823 }
1824 envlist[envc] = 0;
1825
Guido van Rossum246bc171999-02-01 23:54:31 +00001826 if (mode == _OLD_P_OVERLAY)
1827 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001828 spawnval = _spawnve(mode, path, argvlist, envlist);
1829 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001830 (void) posix_error();
1831 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001832#if SIZEOF_LONG == SIZEOF_VOID_P
1833 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001834#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001835 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001836#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001837
1838 fail_2:
1839 while (--envc >= 0)
1840 PyMem_DEL(envlist[envc]);
1841 PyMem_DEL(envlist);
1842 fail_1:
1843 PyMem_DEL(argvlist);
1844 Py_XDECREF(vals);
1845 Py_XDECREF(keys);
1846 return res;
1847}
1848#endif /* HAVE_SPAWNV */
1849
1850
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001851#ifdef HAVE_FORK1
1852static char posix_fork1__doc__[] =
1853"fork1() -> pid\n\
1854Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1855\n\
1856Return 0 to child process and PID of child to parent process.";
1857
1858static PyObject *
1859posix_fork1(self, args)
1860 PyObject *self;
1861 PyObject *args;
1862{
1863 int pid;
1864 if (!PyArg_ParseTuple(args, ":fork1"))
1865 return NULL;
1866 pid = fork1();
1867 if (pid == -1)
1868 return posix_error();
1869 PyOS_AfterFork();
1870 return PyInt_FromLong((long)pid);
1871}
1872#endif
1873
1874
Guido van Rossumad0ee831995-03-01 10:34:45 +00001875#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001876static char posix_fork__doc__[] =
1877"fork() -> pid\n\
1878Fork a child process.\n\
1879\n\
1880Return 0 to child process and PID of child to parent process.";
1881
Barry Warsaw53699e91996-12-10 23:23:01 +00001882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001883posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001884{
1885 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001886 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001887 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001888 pid = fork();
1889 if (pid == -1)
1890 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001891 if (pid == 0)
1892 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001893 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001894}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001895#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001896
Fred Drake8cef4cf2000-06-28 16:40:38 +00001897#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1898#ifdef HAVE_PTY_H
1899#include <pty.h>
1900#else
1901#ifdef HAVE_LIBUTIL_H
1902#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001903#endif /* HAVE_LIBUTIL_H */
1904#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001905#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001906
Thomas Wouters70c21a12000-07-14 14:28:33 +00001907#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001908static char posix_openpty__doc__[] =
1909"openpty() -> (master_fd, slave_fd)\n\
1910Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1911
1912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001913posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001914{
1915 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001916#ifndef HAVE_OPENPTY
1917 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001918#endif
1919
Fred Drake8cef4cf2000-06-28 16:40:38 +00001920 if (!PyArg_ParseTuple(args, ":openpty"))
1921 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001922
1923#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001924 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1925 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001926#else
1927 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1928 if (slave_name == NULL)
1929 return posix_error();
1930
1931 slave_fd = open(slave_name, O_RDWR);
1932 if (slave_fd < 0)
1933 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001934#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001935
Fred Drake8cef4cf2000-06-28 16:40:38 +00001936 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001937
Fred Drake8cef4cf2000-06-28 16:40:38 +00001938}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001939#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001940
1941#ifdef HAVE_FORKPTY
1942static char posix_forkpty__doc__[] =
1943"forkpty() -> (pid, master_fd)\n\
1944Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1945Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1946To both, return fd of newly opened pseudo-terminal.\n";
1947
1948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001949posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001950{
1951 int master_fd, pid;
1952
1953 if (!PyArg_ParseTuple(args, ":forkpty"))
1954 return NULL;
1955 pid = forkpty(&master_fd, NULL, NULL, NULL);
1956 if (pid == -1)
1957 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001958 if (pid == 0)
1959 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001960 return Py_BuildValue("(ii)", pid, master_fd);
1961}
1962#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001963
Guido van Rossumad0ee831995-03-01 10:34:45 +00001964#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001965static char posix_getegid__doc__[] =
1966"getegid() -> egid\n\
1967Return the current process's effective group id.";
1968
Barry Warsaw53699e91996-12-10 23:23:01 +00001969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001970posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001971{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001972 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001973 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001974 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001975}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001976#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001977
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001978
Guido van Rossumad0ee831995-03-01 10:34:45 +00001979#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001980static char posix_geteuid__doc__[] =
1981"geteuid() -> euid\n\
1982Return the current process's effective user id.";
1983
Barry Warsaw53699e91996-12-10 23:23:01 +00001984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001985posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001986{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001987 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001988 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001989 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001990}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001991#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001993
Guido van Rossumad0ee831995-03-01 10:34:45 +00001994#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001995static char posix_getgid__doc__[] =
1996"getgid() -> gid\n\
1997Return the current process's group id.";
1998
Barry Warsaw53699e91996-12-10 23:23:01 +00001999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002000posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002001{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002002 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002003 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002004 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002005}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002006#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002008
2009static char posix_getpid__doc__[] =
2010"getpid() -> pid\n\
2011Return the current process id";
2012
Barry Warsaw53699e91996-12-10 23:23:01 +00002013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002014posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002015{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002016 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002017 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002018 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002019}
2020
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002021
Fred Drakec9680921999-12-13 16:37:25 +00002022#ifdef HAVE_GETGROUPS
2023static char posix_getgroups__doc__[] = "\
2024getgroups() -> list of group IDs\n\
2025Return list of supplemental group IDs for the process.";
2026
2027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002028posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002029{
2030 PyObject *result = NULL;
2031
2032 if (PyArg_ParseTuple(args, ":getgroups")) {
2033#ifdef NGROUPS_MAX
2034#define MAX_GROUPS NGROUPS_MAX
2035#else
2036 /* defined to be 16 on Solaris7, so this should be a small number */
2037#define MAX_GROUPS 64
2038#endif
2039 gid_t grouplist[MAX_GROUPS];
2040 int n;
2041
2042 n = getgroups(MAX_GROUPS, grouplist);
2043 if (n < 0)
2044 posix_error();
2045 else {
2046 result = PyList_New(n);
2047 if (result != NULL) {
2048 PyObject *o;
2049 int i;
2050 for (i = 0; i < n; ++i) {
2051 o = PyInt_FromLong((long)grouplist[i]);
2052 if (o == NULL) {
2053 Py_DECREF(result);
2054 result = NULL;
2055 break;
2056 }
2057 PyList_SET_ITEM(result, i, o);
2058 }
2059 }
2060 }
2061 }
2062 return result;
2063}
2064#endif
2065
Guido van Rossumb6775db1994-08-01 11:34:53 +00002066#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002067static char posix_getpgrp__doc__[] =
2068"getpgrp() -> pgrp\n\
2069Return the current process group id.";
2070
Barry Warsaw53699e91996-12-10 23:23:01 +00002071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002072posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002073{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002074 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002075 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002076#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002077 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002078#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002079 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002080#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002081}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002082#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002084
Guido van Rossumb6775db1994-08-01 11:34:53 +00002085#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002086static char posix_setpgrp__doc__[] =
2087"setpgrp() -> None\n\
2088Make this process a session leader.";
2089
Barry Warsaw53699e91996-12-10 23:23:01 +00002090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002091posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002092{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002093 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002094 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002095#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002096 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002097#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002098 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002099#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002100 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002101 Py_INCREF(Py_None);
2102 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002103}
2104
Guido van Rossumb6775db1994-08-01 11:34:53 +00002105#endif /* HAVE_SETPGRP */
2106
Guido van Rossumad0ee831995-03-01 10:34:45 +00002107#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002108static char posix_getppid__doc__[] =
2109"getppid() -> ppid\n\
2110Return the parent's process id.";
2111
Barry Warsaw53699e91996-12-10 23:23:01 +00002112static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002113posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002114{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002115 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002116 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002117 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002118}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002119#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002121
Fred Drake12c6e2d1999-12-14 21:25:03 +00002122#ifdef HAVE_GETLOGIN
2123static char posix_getlogin__doc__[] = "\
2124getlogin() -> string\n\
2125Return the actual login name.";
2126
2127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002128posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002129{
2130 PyObject *result = NULL;
2131
2132 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002133 char *name;
2134 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002135
Fred Drakea30680b2000-12-06 21:24:28 +00002136 errno = 0;
2137 name = getlogin();
2138 if (name == NULL) {
2139 if (errno)
2140 posix_error();
2141 else
2142 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002143 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002144 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002145 else
2146 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002147 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002148 }
2149 return result;
2150}
2151#endif
2152
Guido van Rossumad0ee831995-03-01 10:34:45 +00002153#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002154static char posix_getuid__doc__[] =
2155"getuid() -> uid\n\
2156Return the current process's user id.";
2157
Barry Warsaw53699e91996-12-10 23:23:01 +00002158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002159posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002160{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002161 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002162 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002163 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002164}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002165#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002167
Guido van Rossumad0ee831995-03-01 10:34:45 +00002168#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002169static char posix_kill__doc__[] =
2170"kill(pid, sig) -> None\n\
2171Kill a process with a signal.";
2172
Barry Warsaw53699e91996-12-10 23:23:01 +00002173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002174posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002175{
2176 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002177 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002178 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002179#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002180 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2181 APIRET rc;
2182 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002183 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002184
2185 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2186 APIRET rc;
2187 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002188 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002189
2190 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002191 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002192#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002193 if (kill(pid, sig) == -1)
2194 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002195#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002196 Py_INCREF(Py_None);
2197 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002198}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002199#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002200
Guido van Rossumc0125471996-06-28 18:55:32 +00002201#ifdef HAVE_PLOCK
2202
2203#ifdef HAVE_SYS_LOCK_H
2204#include <sys/lock.h>
2205#endif
2206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002207static char posix_plock__doc__[] =
2208"plock(op) -> None\n\
2209Lock program segments into memory.";
2210
Barry Warsaw53699e91996-12-10 23:23:01 +00002211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002212posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002213{
2214 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002215 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002216 return NULL;
2217 if (plock(op) == -1)
2218 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002219 Py_INCREF(Py_None);
2220 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002221}
2222#endif
2223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002224
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002225#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002226static char posix_popen__doc__[] =
2227"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2228Open a pipe to/from a command returning a file object.";
2229
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002230#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002231static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002232async_system(const char *command)
2233{
2234 char *p, errormsg[256], args[1024];
2235 RESULTCODES rcodes;
2236 APIRET rc;
2237 char *shell = getenv("COMSPEC");
2238 if (!shell)
2239 shell = "cmd";
2240
2241 strcpy(args, shell);
2242 p = &args[ strlen(args)+1 ];
2243 strcpy(p, "/c ");
2244 strcat(p, command);
2245 p += strlen(p) + 1;
2246 *p = '\0';
2247
2248 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002249 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002250 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002251 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002252 &rcodes, shell);
2253 return rc;
2254}
2255
Guido van Rossumd48f2521997-12-05 22:19:34 +00002256static FILE *
2257popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002258{
2259 HFILE rhan, whan;
2260 FILE *retfd = NULL;
2261 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2262
Guido van Rossumd48f2521997-12-05 22:19:34 +00002263 if (rc != NO_ERROR) {
2264 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002265 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002266 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002267
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002268 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2269 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002270
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002271 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2272 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002273
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002274 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2275 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002276
2277 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002278 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002279 }
2280
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002281 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2282 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002284 close(oldfd); /* And Close Saved STDOUT Handle */
2285 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002286
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002287 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2288 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002289
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002290 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2291 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002292
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002293 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2294 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002295
2296 if (async_system(command) == NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002297 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002298 }
2299
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002300 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2301 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002302
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002303 close(oldfd); /* And Close Saved STDIN Handle */
2304 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002305
Guido van Rossumd48f2521997-12-05 22:19:34 +00002306 } else {
2307 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002308 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002309 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002310}
2311
2312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002313posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002314{
2315 char *name;
2316 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002317 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002318 FILE *fp;
2319 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002320 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002321 return NULL;
2322 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002323 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002324 Py_END_ALLOW_THREADS
2325 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002326 return os2_error(err);
2327
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002328 f = PyFile_FromFile(fp, name, mode, fclose);
2329 if (f != NULL)
2330 PyFile_SetBufSize(f, bufsize);
2331 return f;
2332}
2333
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002334#elif defined(MS_WIN32)
2335
2336/*
2337 * Portable 'popen' replacement for Win32.
2338 *
2339 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2340 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002341 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002342 */
2343
2344#include <malloc.h>
2345#include <io.h>
2346#include <fcntl.h>
2347
2348/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2349#define POPEN_1 1
2350#define POPEN_2 2
2351#define POPEN_3 3
2352#define POPEN_4 4
2353
2354static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002355static int _PyPclose(FILE *file);
2356
2357/*
2358 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002359 * for use when retrieving the process exit code. See _PyPclose() below
2360 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002361 */
2362static PyObject *_PyPopenProcs = NULL;
2363
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002364
2365/* popen that works from a GUI.
2366 *
2367 * The result of this function is a pipe (file) connected to the
2368 * processes stdin or stdout, depending on the requested mode.
2369 */
2370
2371static PyObject *
2372posix_popen(PyObject *self, PyObject *args)
2373{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002374 PyObject *f, *s;
2375 int tm = 0;
2376
2377 char *cmdstring;
2378 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002379 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002380 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002381 return NULL;
2382
2383 s = PyTuple_New(0);
2384
2385 if (*mode == 'r')
2386 tm = _O_RDONLY;
2387 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002388 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002389 return NULL;
2390 } else
2391 tm = _O_WRONLY;
2392
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002393 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002394 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002395 return NULL;
2396 }
2397
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002398 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002399 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002400 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002401 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002402 else
2403 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2404
2405 return f;
2406}
2407
2408/* Variation on win32pipe.popen
2409 *
2410 * The result of this function is a pipe (file) connected to the
2411 * process's stdin, and a pipe connected to the process's stdout.
2412 */
2413
2414static PyObject *
2415win32_popen2(PyObject *self, PyObject *args)
2416{
2417 PyObject *f;
2418 int tm=0;
2419
2420 char *cmdstring;
2421 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002422 int bufsize = -1;
2423 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002424 return NULL;
2425
2426 if (*mode == 't')
2427 tm = _O_TEXT;
2428 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002429 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002430 return NULL;
2431 } else
2432 tm = _O_BINARY;
2433
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002434 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002435 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002436 return NULL;
2437 }
2438
2439 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002440
2441 return f;
2442}
2443
2444/*
2445 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002446 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002447 * The result of this function is 3 pipes - the process's stdin,
2448 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002449 */
2450
2451static PyObject *
2452win32_popen3(PyObject *self, PyObject *args)
2453{
2454 PyObject *f;
2455 int tm = 0;
2456
2457 char *cmdstring;
2458 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002459 int bufsize = -1;
2460 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002461 return NULL;
2462
2463 if (*mode == 't')
2464 tm = _O_TEXT;
2465 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002466 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002467 return NULL;
2468 } else
2469 tm = _O_BINARY;
2470
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002471 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002472 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002473 return NULL;
2474 }
2475
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002476 f = _PyPopen(cmdstring, tm, POPEN_3);
2477
2478 return f;
2479}
2480
2481/*
2482 * Variation on win32pipe.popen
2483 *
2484 * The result of this function is 2 pipes - the processes stdin,
2485 * and stdout+stderr combined as a single pipe.
2486 */
2487
2488static PyObject *
2489win32_popen4(PyObject *self, PyObject *args)
2490{
2491 PyObject *f;
2492 int tm = 0;
2493
2494 char *cmdstring;
2495 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002496 int bufsize = -1;
2497 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002498 return NULL;
2499
2500 if (*mode == 't')
2501 tm = _O_TEXT;
2502 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002503 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002504 return NULL;
2505 } else
2506 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002507
2508 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002509 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002510 return NULL;
2511 }
2512
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002513 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002514
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002515 return f;
2516}
2517
Mark Hammond08501372001-01-31 07:30:29 +00002518static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002519_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002520 HANDLE hStdin,
2521 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002522 HANDLE hStderr,
2523 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002524{
2525 PROCESS_INFORMATION piProcInfo;
2526 STARTUPINFO siStartInfo;
2527 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002528 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002529 int i;
2530 int x;
2531
2532 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002533 char *comshell;
2534
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002535 s1 = (char *)_alloca(i);
2536 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2537 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002538
2539 /* Explicitly check if we are using COMMAND.COM. If we are
2540 * then use the w9xpopen hack.
2541 */
2542 comshell = s1 + x;
2543 while (comshell >= s1 && *comshell != '\\')
2544 --comshell;
2545 ++comshell;
2546
2547 if (GetVersion() < 0x80000000 &&
2548 _stricmp(comshell, "command.com") != 0) {
2549 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002550 x = i + strlen(s3) + strlen(cmdstring) + 1;
2551 s2 = (char *)_alloca(x);
2552 ZeroMemory(s2, x);
2553 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2554 }
2555 else {
2556 /*
Tim Peters402d5982001-08-27 06:37:48 +00002557 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2558 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002559 */
Mark Hammond08501372001-01-31 07:30:29 +00002560 char modulepath[_MAX_PATH];
2561 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002562 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2563 for (i = x = 0; modulepath[i]; i++)
2564 if (modulepath[i] == '\\')
2565 x = i+1;
2566 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002567 /* Create the full-name to w9xpopen, so we can test it exists */
2568 strncat(modulepath,
2569 szConsoleSpawn,
2570 (sizeof(modulepath)/sizeof(modulepath[0]))
2571 -strlen(modulepath));
2572 if (stat(modulepath, &statinfo) != 0) {
2573 /* Eeek - file-not-found - possibly an embedding
2574 situation - see if we can locate it in sys.prefix
2575 */
2576 strncpy(modulepath,
2577 Py_GetExecPrefix(),
2578 sizeof(modulepath)/sizeof(modulepath[0]));
2579 if (modulepath[strlen(modulepath)-1] != '\\')
2580 strcat(modulepath, "\\");
2581 strncat(modulepath,
2582 szConsoleSpawn,
2583 (sizeof(modulepath)/sizeof(modulepath[0]))
2584 -strlen(modulepath));
2585 /* No where else to look - raise an easily identifiable
2586 error, rather than leaving Windows to report
2587 "file not found" - as the user is probably blissfully
2588 unaware this shim EXE is used, and it will confuse them.
2589 (well, it confused me for a while ;-)
2590 */
2591 if (stat(modulepath, &statinfo) != 0) {
2592 PyErr_Format(PyExc_RuntimeError,
2593 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002594 "for popen to work with your shell "
2595 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002596 szConsoleSpawn);
2597 return FALSE;
2598 }
2599 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002600 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2601 strlen(modulepath) +
2602 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002603
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002604 s2 = (char *)_alloca(x);
2605 ZeroMemory(s2, x);
2606 sprintf(
2607 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002608 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002609 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002610 s1,
2611 s3,
2612 cmdstring);
2613 }
2614 }
2615
2616 /* Could be an else here to try cmd.exe / command.com in the path
2617 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002618 else {
Tim Peters402d5982001-08-27 06:37:48 +00002619 PyErr_SetString(PyExc_RuntimeError,
2620 "Cannot locate a COMSPEC environment variable to "
2621 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002622 return FALSE;
2623 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002624
2625 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2626 siStartInfo.cb = sizeof(STARTUPINFO);
2627 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2628 siStartInfo.hStdInput = hStdin;
2629 siStartInfo.hStdOutput = hStdout;
2630 siStartInfo.hStdError = hStderr;
2631 siStartInfo.wShowWindow = SW_HIDE;
2632
2633 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002634 s2,
2635 NULL,
2636 NULL,
2637 TRUE,
2638 CREATE_NEW_CONSOLE,
2639 NULL,
2640 NULL,
2641 &siStartInfo,
2642 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002643 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002644 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002645
Mark Hammondb37a3732000-08-14 04:47:33 +00002646 /* Return process handle */
2647 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002648 return TRUE;
2649 }
Tim Peters402d5982001-08-27 06:37:48 +00002650 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002651 return FALSE;
2652}
2653
2654/* The following code is based off of KB: Q190351 */
2655
2656static PyObject *
2657_PyPopen(char *cmdstring, int mode, int n)
2658{
2659 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2660 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002661 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002662
2663 SECURITY_ATTRIBUTES saAttr;
2664 BOOL fSuccess;
2665 int fd1, fd2, fd3;
2666 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002667 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002668 PyObject *f;
2669
2670 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2671 saAttr.bInheritHandle = TRUE;
2672 saAttr.lpSecurityDescriptor = NULL;
2673
2674 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2675 return win32_error("CreatePipe", NULL);
2676
2677 /* Create new output read handle and the input write handle. Set
2678 * the inheritance properties to FALSE. Otherwise, the child inherits
2679 * the these handles; resulting in non-closeable handles to the pipes
2680 * being created. */
2681 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002682 GetCurrentProcess(), &hChildStdinWrDup, 0,
2683 FALSE,
2684 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002685 if (!fSuccess)
2686 return win32_error("DuplicateHandle", NULL);
2687
2688 /* Close the inheritable version of ChildStdin
2689 that we're using. */
2690 CloseHandle(hChildStdinWr);
2691
2692 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2693 return win32_error("CreatePipe", NULL);
2694
2695 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002696 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2697 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002698 if (!fSuccess)
2699 return win32_error("DuplicateHandle", NULL);
2700
2701 /* Close the inheritable version of ChildStdout
2702 that we're using. */
2703 CloseHandle(hChildStdoutRd);
2704
2705 if (n != POPEN_4) {
2706 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2707 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002708 fSuccess = DuplicateHandle(GetCurrentProcess(),
2709 hChildStderrRd,
2710 GetCurrentProcess(),
2711 &hChildStderrRdDup, 0,
2712 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002713 if (!fSuccess)
2714 return win32_error("DuplicateHandle", NULL);
2715 /* Close the inheritable version of ChildStdErr that we're using. */
2716 CloseHandle(hChildStderrRd);
2717 }
2718
2719 switch (n) {
2720 case POPEN_1:
2721 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2722 case _O_WRONLY | _O_TEXT:
2723 /* Case for writing to child Stdin in text mode. */
2724 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2725 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002726 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002727 PyFile_SetBufSize(f, 0);
2728 /* We don't care about these pipes anymore, so close them. */
2729 CloseHandle(hChildStdoutRdDup);
2730 CloseHandle(hChildStderrRdDup);
2731 break;
2732
2733 case _O_RDONLY | _O_TEXT:
2734 /* Case for reading from child Stdout in text mode. */
2735 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2736 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002737 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002738 PyFile_SetBufSize(f, 0);
2739 /* We don't care about these pipes anymore, so close them. */
2740 CloseHandle(hChildStdinWrDup);
2741 CloseHandle(hChildStderrRdDup);
2742 break;
2743
2744 case _O_RDONLY | _O_BINARY:
2745 /* Case for readinig from child Stdout in binary mode. */
2746 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2747 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002748 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002749 PyFile_SetBufSize(f, 0);
2750 /* We don't care about these pipes anymore, so close them. */
2751 CloseHandle(hChildStdinWrDup);
2752 CloseHandle(hChildStderrRdDup);
2753 break;
2754
2755 case _O_WRONLY | _O_BINARY:
2756 /* Case for writing to child Stdin in binary mode. */
2757 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2758 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002759 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002760 PyFile_SetBufSize(f, 0);
2761 /* We don't care about these pipes anymore, so close them. */
2762 CloseHandle(hChildStdoutRdDup);
2763 CloseHandle(hChildStderrRdDup);
2764 break;
2765 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002766 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002767 break;
2768
2769 case POPEN_2:
2770 case POPEN_4:
2771 {
2772 char *m1, *m2;
2773 PyObject *p1, *p2;
2774
2775 if (mode && _O_TEXT) {
2776 m1 = "r";
2777 m2 = "w";
2778 } else {
2779 m1 = "rb";
2780 m2 = "wb";
2781 }
2782
2783 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2784 f1 = _fdopen(fd1, m2);
2785 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2786 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002787 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002788 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002789 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002790 PyFile_SetBufSize(p2, 0);
2791
2792 if (n != 4)
2793 CloseHandle(hChildStderrRdDup);
2794
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002795 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002796 Py_XDECREF(p1);
2797 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002798 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002799 break;
2800 }
2801
2802 case POPEN_3:
2803 {
2804 char *m1, *m2;
2805 PyObject *p1, *p2, *p3;
2806
2807 if (mode && _O_TEXT) {
2808 m1 = "r";
2809 m2 = "w";
2810 } else {
2811 m1 = "rb";
2812 m2 = "wb";
2813 }
2814
2815 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2816 f1 = _fdopen(fd1, m2);
2817 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2818 f2 = _fdopen(fd2, m1);
2819 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2820 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002821 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002822 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2823 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002824 PyFile_SetBufSize(p1, 0);
2825 PyFile_SetBufSize(p2, 0);
2826 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002827 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002828 Py_XDECREF(p1);
2829 Py_XDECREF(p2);
2830 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002831 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002832 break;
2833 }
2834 }
2835
2836 if (n == POPEN_4) {
2837 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002838 hChildStdinRd,
2839 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002840 hChildStdoutWr,
2841 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002842 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002843 }
2844 else {
2845 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002846 hChildStdinRd,
2847 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002848 hChildStderrWr,
2849 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002850 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002851 }
2852
Mark Hammondb37a3732000-08-14 04:47:33 +00002853 /*
2854 * Insert the files we've created into the process dictionary
2855 * all referencing the list with the process handle and the
2856 * initial number of files (see description below in _PyPclose).
2857 * Since if _PyPclose later tried to wait on a process when all
2858 * handles weren't closed, it could create a deadlock with the
2859 * child, we spend some energy here to try to ensure that we
2860 * either insert all file handles into the dictionary or none
2861 * at all. It's a little clumsy with the various popen modes
2862 * and variable number of files involved.
2863 */
2864 if (!_PyPopenProcs) {
2865 _PyPopenProcs = PyDict_New();
2866 }
2867
2868 if (_PyPopenProcs) {
2869 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2870 int ins_rc[3];
2871
2872 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2873 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2874
2875 procObj = PyList_New(2);
2876 hProcessObj = PyLong_FromVoidPtr(hProcess);
2877 intObj = PyInt_FromLong(file_count);
2878
2879 if (procObj && hProcessObj && intObj) {
2880 PyList_SetItem(procObj,0,hProcessObj);
2881 PyList_SetItem(procObj,1,intObj);
2882
2883 fileObj[0] = PyLong_FromVoidPtr(f1);
2884 if (fileObj[0]) {
2885 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2886 fileObj[0],
2887 procObj);
2888 }
2889 if (file_count >= 2) {
2890 fileObj[1] = PyLong_FromVoidPtr(f2);
2891 if (fileObj[1]) {
2892 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2893 fileObj[1],
2894 procObj);
2895 }
2896 }
2897 if (file_count >= 3) {
2898 fileObj[2] = PyLong_FromVoidPtr(f3);
2899 if (fileObj[2]) {
2900 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2901 fileObj[2],
2902 procObj);
2903 }
2904 }
2905
2906 if (ins_rc[0] < 0 || !fileObj[0] ||
2907 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2908 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2909 /* Something failed - remove any dictionary
2910 * entries that did make it.
2911 */
2912 if (!ins_rc[0] && fileObj[0]) {
2913 PyDict_DelItem(_PyPopenProcs,
2914 fileObj[0]);
2915 }
2916 if (!ins_rc[1] && fileObj[1]) {
2917 PyDict_DelItem(_PyPopenProcs,
2918 fileObj[1]);
2919 }
2920 if (!ins_rc[2] && fileObj[2]) {
2921 PyDict_DelItem(_PyPopenProcs,
2922 fileObj[2]);
2923 }
2924 }
2925 }
2926
2927 /*
2928 * Clean up our localized references for the dictionary keys
2929 * and value since PyDict_SetItem will Py_INCREF any copies
2930 * that got placed in the dictionary.
2931 */
2932 Py_XDECREF(procObj);
2933 Py_XDECREF(fileObj[0]);
2934 Py_XDECREF(fileObj[1]);
2935 Py_XDECREF(fileObj[2]);
2936 }
2937
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002938 /* Child is launched. Close the parents copy of those pipe
2939 * handles that only the child should have open. You need to
2940 * make sure that no handles to the write end of the output pipe
2941 * are maintained in this process or else the pipe will not close
2942 * when the child process exits and the ReadFile will hang. */
2943
2944 if (!CloseHandle(hChildStdinRd))
2945 return win32_error("CloseHandle", NULL);
2946
2947 if (!CloseHandle(hChildStdoutWr))
2948 return win32_error("CloseHandle", NULL);
2949
2950 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2951 return win32_error("CloseHandle", NULL);
2952
2953 return f;
2954}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002955
2956/*
2957 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2958 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002959 *
2960 * This function uses the _PyPopenProcs dictionary in order to map the
2961 * input file pointer to information about the process that was
2962 * originally created by the popen* call that created the file pointer.
2963 * The dictionary uses the file pointer as a key (with one entry
2964 * inserted for each file returned by the original popen* call) and a
2965 * single list object as the value for all files from a single call.
2966 * The list object contains the Win32 process handle at [0], and a file
2967 * count at [1], which is initialized to the total number of file
2968 * handles using that list.
2969 *
2970 * This function closes whichever handle it is passed, and decrements
2971 * the file count in the dictionary for the process handle pointed to
2972 * by this file. On the last close (when the file count reaches zero),
2973 * this function will wait for the child process and then return its
2974 * exit code as the result of the close() operation. This permits the
2975 * files to be closed in any order - it is always the close() of the
2976 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002977 */
Tim Peters736aa322000-09-01 06:51:24 +00002978
2979 /* RED_FLAG 31-Aug-2000 Tim
2980 * This is always called (today!) between a pair of
2981 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2982 * macros. So the thread running this has no valid thread state, as
2983 * far as Python is concerned. However, this calls some Python API
2984 * functions that cannot be called safely without a valid thread
2985 * state, in particular PyDict_GetItem.
2986 * As a temporary hack (although it may last for years ...), we
2987 * *rely* on not having a valid thread state in this function, in
2988 * order to create our own "from scratch".
2989 * This will deadlock if _PyPclose is ever called by a thread
2990 * holding the global lock.
2991 */
2992
Fredrik Lundh56055a42000-07-23 19:47:12 +00002993static int _PyPclose(FILE *file)
2994{
Fredrik Lundh20318932000-07-26 17:29:12 +00002995 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00002996 DWORD exit_code;
2997 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00002998 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
2999 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003000#ifdef WITH_THREAD
3001 PyInterpreterState* pInterpreterState;
3002 PyThreadState* pThreadState;
3003#endif
3004
Fredrik Lundh20318932000-07-26 17:29:12 +00003005 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003006 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003007 */
3008 result = fclose(file);
3009
Tim Peters736aa322000-09-01 06:51:24 +00003010#ifdef WITH_THREAD
3011 /* Bootstrap a valid thread state into existence. */
3012 pInterpreterState = PyInterpreterState_New();
3013 if (!pInterpreterState) {
3014 /* Well, we're hosed now! We don't have a thread
3015 * state, so can't call a nice error routine, or raise
3016 * an exception. Just die.
3017 */
3018 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003019 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003020 return -1; /* unreachable */
3021 }
3022 pThreadState = PyThreadState_New(pInterpreterState);
3023 if (!pThreadState) {
3024 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003025 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003026 return -1; /* unreachable */
3027 }
3028 /* Grab the global lock. Note that this will deadlock if the
3029 * current thread already has the lock! (see RED_FLAG comments
3030 * before this function)
3031 */
3032 PyEval_RestoreThread(pThreadState);
3033#endif
3034
Fredrik Lundh56055a42000-07-23 19:47:12 +00003035 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003036 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3037 (procObj = PyDict_GetItem(_PyPopenProcs,
3038 fileObj)) != NULL &&
3039 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3040 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3041
3042 hProcess = PyLong_AsVoidPtr(hProcessObj);
3043 file_count = PyInt_AsLong(intObj);
3044
3045 if (file_count > 1) {
3046 /* Still other files referencing process */
3047 file_count--;
3048 PyList_SetItem(procObj,1,
3049 PyInt_FromLong(file_count));
3050 } else {
3051 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003052 if (result != EOF &&
3053 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3054 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003055 /* Possible truncation here in 16-bit environments, but
3056 * real exit codes are just the lower byte in any event.
3057 */
3058 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003059 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003060 /* Indicate failure - this will cause the file object
3061 * to raise an I/O error and translate the last Win32
3062 * error code from errno. We do have a problem with
3063 * last errors that overlap the normal errno table,
3064 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003065 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003066 if (result != EOF) {
3067 /* If the error wasn't from the fclose(), then
3068 * set errno for the file object error handling.
3069 */
3070 errno = GetLastError();
3071 }
3072 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003073 }
3074
3075 /* Free up the native handle at this point */
3076 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003077 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003078
Mark Hammondb37a3732000-08-14 04:47:33 +00003079 /* Remove this file pointer from dictionary */
3080 PyDict_DelItem(_PyPopenProcs, fileObj);
3081
3082 if (PyDict_Size(_PyPopenProcs) == 0) {
3083 Py_DECREF(_PyPopenProcs);
3084 _PyPopenProcs = NULL;
3085 }
3086
3087 } /* if object retrieval ok */
3088
3089 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003090 } /* if _PyPopenProcs */
3091
Tim Peters736aa322000-09-01 06:51:24 +00003092#ifdef WITH_THREAD
3093 /* Tear down the thread & interpreter states.
3094 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003095 * call the thread clear & delete functions, and indeed insist on
3096 * doing that themselves. The lock must be held during the clear, but
3097 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003098 */
3099 PyInterpreterState_Clear(pInterpreterState);
3100 PyEval_ReleaseThread(pThreadState);
3101 PyInterpreterState_Delete(pInterpreterState);
3102#endif
3103
Fredrik Lundh56055a42000-07-23 19:47:12 +00003104 return result;
3105}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003106
3107#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003109posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003110{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003111 char *name;
3112 char *mode = "r";
3113 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003114 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003115 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003116 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003117 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003118 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003119 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003120 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003121 if (fp == NULL)
3122 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003123 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003124 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003125 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003126 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003127}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003128#endif
3129
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003130#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003132
Guido van Rossumb6775db1994-08-01 11:34:53 +00003133#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003134static char posix_setuid__doc__[] =
3135"setuid(uid) -> None\n\
3136Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003138posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003139{
3140 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003141 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003142 return NULL;
3143 if (setuid(uid) < 0)
3144 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003145 Py_INCREF(Py_None);
3146 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003147}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003148#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003149
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003150
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003151#ifdef HAVE_SETEUID
3152static char posix_seteuid__doc__[] =
3153"seteuid(uid) -> None\n\
3154Set the current process's effective user id.";
3155static PyObject *
3156posix_seteuid (PyObject *self, PyObject *args)
3157{
3158 int euid;
3159 if (!PyArg_ParseTuple(args, "i", &euid)) {
3160 return NULL;
3161 } else if (seteuid(euid) < 0) {
3162 return posix_error();
3163 } else {
3164 Py_INCREF(Py_None);
3165 return Py_None;
3166 }
3167}
3168#endif /* HAVE_SETEUID */
3169
3170#ifdef HAVE_SETEGID
3171static char posix_setegid__doc__[] =
3172"setegid(gid) -> None\n\
3173Set the current process's effective group id.";
3174static PyObject *
3175posix_setegid (PyObject *self, PyObject *args)
3176{
3177 int egid;
3178 if (!PyArg_ParseTuple(args, "i", &egid)) {
3179 return NULL;
3180 } else if (setegid(egid) < 0) {
3181 return posix_error();
3182 } else {
3183 Py_INCREF(Py_None);
3184 return Py_None;
3185 }
3186}
3187#endif /* HAVE_SETEGID */
3188
3189#ifdef HAVE_SETREUID
3190static char posix_setreuid__doc__[] =
3191"seteuid(ruid, euid) -> None\n\
3192Set the current process's real and effective user ids.";
3193static PyObject *
3194posix_setreuid (PyObject *self, PyObject *args)
3195{
3196 int ruid, euid;
3197 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3198 return NULL;
3199 } else if (setreuid(ruid, euid) < 0) {
3200 return posix_error();
3201 } else {
3202 Py_INCREF(Py_None);
3203 return Py_None;
3204 }
3205}
3206#endif /* HAVE_SETREUID */
3207
3208#ifdef HAVE_SETREGID
3209static char posix_setregid__doc__[] =
3210"setegid(rgid, egid) -> None\n\
3211Set the current process's real and effective group ids.";
3212static PyObject *
3213posix_setregid (PyObject *self, PyObject *args)
3214{
3215 int rgid, egid;
3216 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3217 return NULL;
3218 } else if (setregid(rgid, egid) < 0) {
3219 return posix_error();
3220 } else {
3221 Py_INCREF(Py_None);
3222 return Py_None;
3223 }
3224}
3225#endif /* HAVE_SETREGID */
3226
Guido van Rossumb6775db1994-08-01 11:34:53 +00003227#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003228static char posix_setgid__doc__[] =
3229"setgid(gid) -> None\n\
3230Set the current process's group id.";
3231
Barry Warsaw53699e91996-12-10 23:23:01 +00003232static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003233posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003234{
3235 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003236 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003237 return NULL;
3238 if (setgid(gid) < 0)
3239 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003240 Py_INCREF(Py_None);
3241 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003242}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003243#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003244
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003245#ifdef HAVE_SETGROUPS
3246static char posix_setgroups__doc__[] =
3247"setgroups(list) -> None\n\
3248Set the groups of the current process to list.";
3249
3250static PyObject *
3251posix_setgroups(PyObject *self, PyObject *args)
3252{
3253 PyObject *groups;
3254 int i, len;
3255 gid_t grouplist[MAX_GROUPS];
3256
3257 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3258 return NULL;
3259 if (!PySequence_Check(groups)) {
3260 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3261 return NULL;
3262 }
3263 len = PySequence_Size(groups);
3264 if (len > MAX_GROUPS) {
3265 PyErr_SetString(PyExc_ValueError, "too many groups");
3266 return NULL;
3267 }
3268 for(i = 0; i < len; i++) {
3269 PyObject *elem;
3270 elem = PySequence_GetItem(groups, i);
3271 if (!elem)
3272 return NULL;
3273 if (!PyInt_Check(elem)) {
3274 PyErr_SetString(PyExc_TypeError,
3275 "groups must be integers");
3276 Py_DECREF(elem);
3277 return NULL;
3278 }
3279 /* XXX: check that value fits into gid_t. */
3280 grouplist[i] = PyInt_AsLong(elem);
3281 Py_DECREF(elem);
3282 }
3283
3284 if (setgroups(len, grouplist) < 0)
3285 return posix_error();
3286 Py_INCREF(Py_None);
3287 return Py_None;
3288}
3289#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003290
Guido van Rossumb6775db1994-08-01 11:34:53 +00003291#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003292static char posix_waitpid__doc__[] =
3293"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003294Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003295
Barry Warsaw53699e91996-12-10 23:23:01 +00003296static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003297posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003298{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003299 int pid, options;
3300#ifdef UNION_WAIT
3301 union wait status;
3302#define status_i (status.w_status)
3303#else
3304 int status;
3305#define status_i status
3306#endif
3307 status_i = 0;
3308
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003309 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003310 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003311 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003312#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003313 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003314#else
3315 pid = waitpid(pid, &status, options);
3316#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003317 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003318 if (pid == -1)
3319 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003320 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003321 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003322}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003323#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003325
Guido van Rossumad0ee831995-03-01 10:34:45 +00003326#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003327static char posix_wait__doc__[] =
3328"wait() -> (pid, status)\n\
3329Wait for completion of a child process.";
3330
Barry Warsaw53699e91996-12-10 23:23:01 +00003331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003332posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003333{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003334 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003335#ifdef UNION_WAIT
3336 union wait status;
3337#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003338#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003339 int status;
3340#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003341#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003342 if (!PyArg_ParseTuple(args, ":wait"))
3343 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003344 status_i = 0;
3345 Py_BEGIN_ALLOW_THREADS
3346 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003347 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003348 if (pid == -1)
3349 return posix_error();
3350 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003351 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003352#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003353}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003354#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003356
3357static char posix_lstat__doc__[] =
3358"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3359Like stat(path), but do not follow symbolic links.";
3360
Barry Warsaw53699e91996-12-10 23:23:01 +00003361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003362posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003363{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003364#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003365 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003366#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003367 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003368#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003369}
3370
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003371
Guido van Rossumb6775db1994-08-01 11:34:53 +00003372#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003373static char posix_readlink__doc__[] =
3374"readlink(path) -> path\n\
3375Return a string representing the path to which the symbolic link points.";
3376
Barry Warsaw53699e91996-12-10 23:23:01 +00003377static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003378posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003379{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003380 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003381 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003382 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003383 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003384 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003385 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003386 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003387 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003388 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003389 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003390 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003391}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003392#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003394
Guido van Rossumb6775db1994-08-01 11:34:53 +00003395#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003396static char posix_symlink__doc__[] =
3397"symlink(src, dst) -> None\n\
3398Create a symbolic link.";
3399
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003400static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003401posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003402{
Mark Hammondef8b6542001-05-13 08:04:26 +00003403 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003404}
3405#endif /* HAVE_SYMLINK */
3406
3407
3408#ifdef HAVE_TIMES
3409#ifndef HZ
3410#define HZ 60 /* Universal constant :-) */
3411#endif /* HZ */
3412
Guido van Rossumd48f2521997-12-05 22:19:34 +00003413#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3414static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003415system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003416{
3417 ULONG value = 0;
3418
3419 Py_BEGIN_ALLOW_THREADS
3420 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3421 Py_END_ALLOW_THREADS
3422
3423 return value;
3424}
3425
3426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003427posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003428{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003429 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003430 return NULL;
3431
3432 /* Currently Only Uptime is Provided -- Others Later */
3433 return Py_BuildValue("ddddd",
3434 (double)0 /* t.tms_utime / HZ */,
3435 (double)0 /* t.tms_stime / HZ */,
3436 (double)0 /* t.tms_cutime / HZ */,
3437 (double)0 /* t.tms_cstime / HZ */,
3438 (double)system_uptime() / 1000);
3439}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003440#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003442posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003443{
3444 struct tms t;
3445 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003446 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003447 return NULL;
3448 errno = 0;
3449 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003450 if (c == (clock_t) -1)
3451 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003452 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003453 (double)t.tms_utime / HZ,
3454 (double)t.tms_stime / HZ,
3455 (double)t.tms_cutime / HZ,
3456 (double)t.tms_cstime / HZ,
3457 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003458}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003459#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003460#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003461
3462
Guido van Rossum87755a21996-09-07 00:59:43 +00003463#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003464#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003466posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003467{
3468 FILETIME create, exit, kernel, user;
3469 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003470 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003471 return NULL;
3472 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003473 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3474 /* The fields of a FILETIME structure are the hi and lo part
3475 of a 64-bit value expressed in 100 nanosecond units.
3476 1e7 is one second in such units; 1e-7 the inverse.
3477 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3478 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003479 return Py_BuildValue(
3480 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003481 (double)(kernel.dwHighDateTime*429.4967296 +
3482 kernel.dwLowDateTime*1e-7),
3483 (double)(user.dwHighDateTime*429.4967296 +
3484 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003485 (double)0,
3486 (double)0,
3487 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003488}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003489#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003490
3491#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003492static char posix_times__doc__[] =
3493"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3494Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003495#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003496
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003497
Guido van Rossumb6775db1994-08-01 11:34:53 +00003498#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003499static char posix_setsid__doc__[] =
3500"setsid() -> None\n\
3501Call the system call setsid().";
3502
Barry Warsaw53699e91996-12-10 23:23:01 +00003503static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003504posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003505{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003506 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003507 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003508 if (setsid() < 0)
3509 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003510 Py_INCREF(Py_None);
3511 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003512}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003513#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003514
Guido van Rossumb6775db1994-08-01 11:34:53 +00003515#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003516static char posix_setpgid__doc__[] =
3517"setpgid(pid, pgrp) -> None\n\
3518Call the system call setpgid().";
3519
Barry Warsaw53699e91996-12-10 23:23:01 +00003520static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003521posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003522{
3523 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003524 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003525 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003526 if (setpgid(pid, pgrp) < 0)
3527 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003528 Py_INCREF(Py_None);
3529 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003530}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003531#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003532
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003533
Guido van Rossumb6775db1994-08-01 11:34:53 +00003534#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003535static char posix_tcgetpgrp__doc__[] =
3536"tcgetpgrp(fd) -> pgid\n\
3537Return the process group associated with the terminal given by a fd.";
3538
Barry Warsaw53699e91996-12-10 23:23:01 +00003539static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003540posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003541{
3542 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003543 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003544 return NULL;
3545 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003546 if (pgid < 0)
3547 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003548 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003549}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003550#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003552
Guido van Rossumb6775db1994-08-01 11:34:53 +00003553#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003554static char posix_tcsetpgrp__doc__[] =
3555"tcsetpgrp(fd, pgid) -> None\n\
3556Set the process group associated with the terminal given by a fd.";
3557
Barry Warsaw53699e91996-12-10 23:23:01 +00003558static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003559posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003560{
3561 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003562 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003563 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003564 if (tcsetpgrp(fd, pgid) < 0)
3565 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003566 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003567 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003568}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003569#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003570
Guido van Rossum687dd131993-05-17 08:34:16 +00003571/* Functions acting on file descriptors */
3572
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003573static char posix_open__doc__[] =
3574"open(filename, flag [, mode=0777]) -> fd\n\
3575Open a file (for low level IO).";
3576
Barry Warsaw53699e91996-12-10 23:23:01 +00003577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003578posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003579{
Mark Hammondef8b6542001-05-13 08:04:26 +00003580 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003581 int flag;
3582 int mode = 0777;
3583 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003584 if (!PyArg_ParseTuple(args, "eti|i",
3585 Py_FileSystemDefaultEncoding, &file,
3586 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003587 return NULL;
3588
Barry Warsaw53699e91996-12-10 23:23:01 +00003589 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003590 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003591 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003592 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003593 return posix_error_with_allocated_filename(file);
3594 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003595 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003596}
3597
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003598
3599static char posix_close__doc__[] =
3600"close(fd) -> None\n\
3601Close a file descriptor (for low level IO).";
3602
Barry Warsaw53699e91996-12-10 23:23:01 +00003603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003604posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003605{
3606 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003607 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003608 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003609 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003610 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003611 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003612 if (res < 0)
3613 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003614 Py_INCREF(Py_None);
3615 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003616}
3617
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003618
3619static char posix_dup__doc__[] =
3620"dup(fd) -> fd2\n\
3621Return a duplicate of a file descriptor.";
3622
Barry Warsaw53699e91996-12-10 23:23:01 +00003623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003624posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003625{
3626 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003627 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003628 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003629 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003630 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003631 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003632 if (fd < 0)
3633 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003634 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003635}
3636
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003637
3638static char posix_dup2__doc__[] =
3639"dup2(fd, fd2) -> None\n\
3640Duplicate file descriptor.";
3641
Barry Warsaw53699e91996-12-10 23:23:01 +00003642static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003643posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003644{
3645 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003646 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003647 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003648 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003649 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003650 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003651 if (res < 0)
3652 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003653 Py_INCREF(Py_None);
3654 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003655}
3656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003657
3658static char posix_lseek__doc__[] =
3659"lseek(fd, pos, how) -> newpos\n\
3660Set the current position of a file descriptor.";
3661
Barry Warsaw53699e91996-12-10 23:23:01 +00003662static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003663posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003664{
3665 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003666#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003667 LONG_LONG pos, res;
3668#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003669 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003670#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003671 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003672 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003673 return NULL;
3674#ifdef SEEK_SET
3675 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3676 switch (how) {
3677 case 0: how = SEEK_SET; break;
3678 case 1: how = SEEK_CUR; break;
3679 case 2: how = SEEK_END; break;
3680 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003681#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003682
3683#if !defined(HAVE_LARGEFILE_SUPPORT)
3684 pos = PyInt_AsLong(posobj);
3685#else
3686 pos = PyLong_Check(posobj) ?
3687 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3688#endif
3689 if (PyErr_Occurred())
3690 return NULL;
3691
Barry Warsaw53699e91996-12-10 23:23:01 +00003692 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003693#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003694 res = _lseeki64(fd, pos, how);
3695#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003696 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003697#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003698 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003699 if (res < 0)
3700 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003701
3702#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003703 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003704#else
3705 return PyLong_FromLongLong(res);
3706#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003707}
3708
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003709
3710static char posix_read__doc__[] =
3711"read(fd, buffersize) -> string\n\
3712Read a file descriptor.";
3713
Barry Warsaw53699e91996-12-10 23:23:01 +00003714static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003715posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003716{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003717 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003718 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003719 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003720 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003721 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003722 if (buffer == NULL)
3723 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003724 Py_BEGIN_ALLOW_THREADS
3725 n = read(fd, PyString_AsString(buffer), size);
3726 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003727 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003728 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003729 return posix_error();
3730 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003731 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003732 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003733 return buffer;
3734}
3735
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003736
3737static char posix_write__doc__[] =
3738"write(fd, string) -> byteswritten\n\
3739Write a string to a file descriptor.";
3740
Barry Warsaw53699e91996-12-10 23:23:01 +00003741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003742posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003743{
3744 int fd, size;
3745 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003746 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003747 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003748 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003749 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003750 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003751 if (size < 0)
3752 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003753 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003754}
3755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003756
3757static char posix_fstat__doc__[]=
3758"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3759Like stat(), but for an open file descriptor.";
3760
Barry Warsaw53699e91996-12-10 23:23:01 +00003761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003762posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003763{
3764 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003765 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003766 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003767 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003768 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003769 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003770 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003771 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003772 if (res != 0)
3773 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003774
3775 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003776}
3777
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003778
3779static char posix_fdopen__doc__[] =
3780"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3781Return an open file object connected to a file descriptor.";
3782
Barry Warsaw53699e91996-12-10 23:23:01 +00003783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003784posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003785{
Guido van Rossum687dd131993-05-17 08:34:16 +00003786 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003787 char *mode = "r";
3788 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003789 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003790 PyObject *f;
3791 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003792 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003793
Barry Warsaw53699e91996-12-10 23:23:01 +00003794 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003795 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003796 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003797 if (fp == NULL)
3798 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003799 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003800 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003801 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003802 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003803}
3804
Skip Montanaro1517d842000-07-19 14:34:14 +00003805static char posix_isatty__doc__[] =
3806"isatty(fd) -> Boolean\n\
3807Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003808connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003809
3810static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003811posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003812{
3813 int fd;
3814 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3815 return NULL;
3816 return Py_BuildValue("i", isatty(fd));
3817}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003818
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003819#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003820static char posix_pipe__doc__[] =
3821"pipe() -> (read_end, write_end)\n\
3822Create a pipe.";
3823
Barry Warsaw53699e91996-12-10 23:23:01 +00003824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003825posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003826{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003827#if defined(PYOS_OS2)
3828 HFILE read, write;
3829 APIRET rc;
3830
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003831 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003832 return NULL;
3833
3834 Py_BEGIN_ALLOW_THREADS
3835 rc = DosCreatePipe( &read, &write, 4096);
3836 Py_END_ALLOW_THREADS
3837 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003838 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003839
3840 return Py_BuildValue("(ii)", read, write);
3841#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003842#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003843 int fds[2];
3844 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003845 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003846 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003847 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003848 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003849 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003850 if (res != 0)
3851 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003852 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003853#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003854 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003855 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003856 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003857 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003858 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003859 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003860 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003861 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003862 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003863 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003864 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3865 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003866 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003867#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003868#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003869}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003870#endif /* HAVE_PIPE */
3871
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003872
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003873#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003874static char posix_mkfifo__doc__[] =
3875"mkfifo(file, [, mode=0666]) -> None\n\
3876Create a FIFO (a POSIX named pipe).";
3877
Barry Warsaw53699e91996-12-10 23:23:01 +00003878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003879posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003880{
3881 char *file;
3882 int mode = 0666;
3883 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003884 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003885 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003886 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003887 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003888 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003889 if (res < 0)
3890 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003891 Py_INCREF(Py_None);
3892 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003893}
3894#endif
3895
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003896
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003897#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003898static char posix_ftruncate__doc__[] =
3899"ftruncate(fd, length) -> None\n\
3900Truncate a file to a specified length.";
3901
Barry Warsaw53699e91996-12-10 23:23:01 +00003902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003903posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003904{
3905 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003906 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003907 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003908 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003909
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003910 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003911 return NULL;
3912
3913#if !defined(HAVE_LARGEFILE_SUPPORT)
3914 length = PyInt_AsLong(lenobj);
3915#else
3916 length = PyLong_Check(lenobj) ?
3917 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3918#endif
3919 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003920 return NULL;
3921
Barry Warsaw53699e91996-12-10 23:23:01 +00003922 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003923 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003924 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003925 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003926 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003927 return NULL;
3928 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003929 Py_INCREF(Py_None);
3930 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003931}
3932#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003933
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003934#ifdef NeXT
3935#define HAVE_PUTENV
3936/* Steve Spicklemire got this putenv from NeXTAnswers */
3937static int
3938putenv(char *newval)
3939{
3940 extern char **environ;
3941
3942 static int firstTime = 1;
3943 char **ep;
3944 char *cp;
3945 int esiz;
3946 char *np;
3947
3948 if (!(np = strchr(newval, '=')))
3949 return 1;
3950 *np = '\0';
3951
3952 /* look it up */
3953 for (ep=environ ; *ep ; ep++)
3954 {
3955 /* this should always be true... */
3956 if (cp = strchr(*ep, '='))
3957 {
3958 *cp = '\0';
3959 if (!strcmp(*ep, newval))
3960 {
3961 /* got it! */
3962 *cp = '=';
3963 break;
3964 }
3965 *cp = '=';
3966 }
3967 else
3968 {
3969 *np = '=';
3970 return 1;
3971 }
3972 }
3973
3974 *np = '=';
3975 if (*ep)
3976 {
3977 /* the string was already there:
3978 just replace it with the new one */
3979 *ep = newval;
3980 return 0;
3981 }
3982
3983 /* expand environ by one */
3984 for (esiz=2, ep=environ ; *ep ; ep++)
3985 esiz++;
3986 if (firstTime)
3987 {
3988 char **epp;
3989 char **newenv;
3990 if (!(newenv = malloc(esiz * sizeof(char *))))
3991 return 1;
3992
3993 for (ep=environ, epp=newenv ; *ep ;)
3994 *epp++ = *ep++;
3995 *epp++ = newval;
3996 *epp = (char *) 0;
3997 environ = newenv;
3998 }
3999 else
4000 {
4001 if (!(environ = realloc(environ, esiz * sizeof(char *))))
4002 return 1;
4003 environ[esiz - 2] = newval;
4004 environ[esiz - 1] = (char *) 0;
4005 firstTime = 0;
4006 }
4007
4008 return 0;
4009}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00004010#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004012
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004013#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004014static char posix_putenv__doc__[] =
4015"putenv(key, value) -> None\n\
4016Change or add an environment variable.";
4017
Fred Drake762e2061999-08-26 17:23:54 +00004018/* Save putenv() parameters as values here, so we can collect them when they
4019 * get re-set with another call for the same key. */
4020static PyObject *posix_putenv_garbage;
4021
Barry Warsaw53699e91996-12-10 23:23:01 +00004022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004023posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004024{
4025 char *s1, *s2;
4026 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004027 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004028
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004029 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004030 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004031
4032#if defined(PYOS_OS2)
4033 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4034 APIRET rc;
4035
4036 if (strlen(s2) == 0) /* If New Value is an Empty String */
4037 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4038
4039 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4040 if (rc != NO_ERROR)
4041 return os2_error(rc);
4042
4043 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4044 APIRET rc;
4045
4046 if (strlen(s2) == 0) /* If New Value is an Empty String */
4047 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4048
4049 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4050 if (rc != NO_ERROR)
4051 return os2_error(rc);
4052 } else {
4053#endif
4054
Fred Drake762e2061999-08-26 17:23:54 +00004055 /* XXX This can leak memory -- not easy to fix :-( */
4056 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
4057 if (newstr == NULL)
4058 return PyErr_NoMemory();
4059 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004060 (void) sprintf(new, "%s=%s", s1, s2);
4061 if (putenv(new)) {
4062 posix_error();
4063 return NULL;
4064 }
Fred Drake762e2061999-08-26 17:23:54 +00004065 /* Install the first arg and newstr in posix_putenv_garbage;
4066 * this will cause previous value to be collected. This has to
4067 * happen after the real putenv() call because the old value
4068 * was still accessible until then. */
4069 if (PyDict_SetItem(posix_putenv_garbage,
4070 PyTuple_GET_ITEM(args, 0), newstr)) {
4071 /* really not much we can do; just leak */
4072 PyErr_Clear();
4073 }
4074 else {
4075 Py_DECREF(newstr);
4076 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004077
4078#if defined(PYOS_OS2)
4079 }
4080#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004081 Py_INCREF(Py_None);
4082 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004083}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004084#endif /* putenv */
4085
4086#ifdef HAVE_STRERROR
4087static char posix_strerror__doc__[] =
4088"strerror(code) -> string\n\
4089Translate an error code to a message string.";
4090
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004092posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004093{
4094 int code;
4095 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004096 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004097 return NULL;
4098 message = strerror(code);
4099 if (message == NULL) {
4100 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004101 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004102 return NULL;
4103 }
4104 return PyString_FromString(message);
4105}
4106#endif /* strerror */
4107
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004108
Guido van Rossumc9641791998-08-04 15:26:23 +00004109#ifdef HAVE_SYS_WAIT_H
4110
4111#ifdef WIFSTOPPED
4112static char posix_WIFSTOPPED__doc__[] =
4113"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004114Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004115
4116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004117posix_WIFSTOPPED(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:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004129 {
4130 return NULL;
4131 }
4132
4133 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004134#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004135}
4136#endif /* WIFSTOPPED */
4137
4138#ifdef WIFSIGNALED
4139static char posix_WIFSIGNALED__doc__[] =
4140"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004141Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004142
4143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004144posix_WIFSIGNALED(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:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004156 {
4157 return NULL;
4158 }
4159
4160 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004161#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004162}
4163#endif /* WIFSIGNALED */
4164
4165#ifdef WIFEXITED
4166static char posix_WIFEXITED__doc__[] =
4167"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004168Return true if the process returning 'status' exited using the exit()\n\
4169system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004170
4171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004172posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004173{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004174#ifdef UNION_WAIT
4175 union wait status;
4176#define status_i (status.w_status)
4177#else
4178 int status;
4179#define status_i status
4180#endif
4181 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004182
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004183 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004184 {
4185 return NULL;
4186 }
4187
4188 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004189#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004190}
4191#endif /* WIFEXITED */
4192
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004193#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004194static char posix_WEXITSTATUS__doc__[] =
4195"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004196Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004197
4198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004199posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004200{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004201#ifdef UNION_WAIT
4202 union wait status;
4203#define status_i (status.w_status)
4204#else
4205 int status;
4206#define status_i status
4207#endif
4208 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004209
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004210 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004211 {
4212 return NULL;
4213 }
4214
4215 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004216#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004217}
4218#endif /* WEXITSTATUS */
4219
4220#ifdef WTERMSIG
4221static char posix_WTERMSIG__doc__[] =
4222"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004223Return the signal that terminated the process that provided the 'status'\n\
4224value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004225
4226static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004227posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004228{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004229#ifdef UNION_WAIT
4230 union wait status;
4231#define status_i (status.w_status)
4232#else
4233 int status;
4234#define status_i status
4235#endif
4236 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004237
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004238 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004239 {
4240 return NULL;
4241 }
4242
4243 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004244#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004245}
4246#endif /* WTERMSIG */
4247
4248#ifdef WSTOPSIG
4249static char posix_WSTOPSIG__doc__[] =
4250"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004251Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004252
4253static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004254posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004255{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004256#ifdef UNION_WAIT
4257 union wait status;
4258#define status_i (status.w_status)
4259#else
4260 int status;
4261#define status_i status
4262#endif
4263 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004264
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004265 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004266 {
4267 return NULL;
4268 }
4269
4270 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004271#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004272}
4273#endif /* WSTOPSIG */
4274
4275#endif /* HAVE_SYS_WAIT_H */
4276
4277
Guido van Rossum94f6f721999-01-06 18:42:14 +00004278#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004279#ifdef _SCO_DS
4280/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4281 needed definitions in sys/statvfs.h */
4282#define _SVID3
4283#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004284#include <sys/statvfs.h>
4285
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004286static PyObject*
4287_pystatvfs_fromstructstatvfs(struct statvfs st) {
4288 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4289 if (v == NULL)
4290 return NULL;
4291
4292#if !defined(HAVE_LARGEFILE_SUPPORT)
4293 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4294 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4295 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4296 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4297 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4298 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4299 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4300 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4301 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4302 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4303#else
4304 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4305 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4306 PyStructSequence_SET_ITEM(v, 2,
4307 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
4308 PyStructSequence_SET_ITEM(v, 3,
4309 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4310 PyStructSequence_SET_ITEM(v, 4,
4311 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
4312 PyStructSequence_SET_ITEM(v, 5,
4313 PyLong_FromLongLong((LONG_LONG) st.f_files));
4314 PyStructSequence_SET_ITEM(v, 6,
4315 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
4316 PyStructSequence_SET_ITEM(v, 7,
4317 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4318 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4319 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4320#endif
4321
4322 return v;
4323}
4324
Guido van Rossum94f6f721999-01-06 18:42:14 +00004325static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004326"fstatvfs(fd) -> \n\
4327 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004328Perform an fstatvfs system call on the given fd.";
4329
4330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004331posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004332{
4333 int fd, res;
4334 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004335
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004336 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004337 return NULL;
4338 Py_BEGIN_ALLOW_THREADS
4339 res = fstatvfs(fd, &st);
4340 Py_END_ALLOW_THREADS
4341 if (res != 0)
4342 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004343
4344 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004345}
4346#endif /* HAVE_FSTATVFS */
4347
4348
4349#if defined(HAVE_STATVFS)
4350#include <sys/statvfs.h>
4351
4352static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004353"statvfs(path) -> \n\
4354 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004355Perform a statvfs system call on the given path.";
4356
4357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004358posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004359{
4360 char *path;
4361 int res;
4362 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004363 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004364 return NULL;
4365 Py_BEGIN_ALLOW_THREADS
4366 res = statvfs(path, &st);
4367 Py_END_ALLOW_THREADS
4368 if (res != 0)
4369 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004370
4371 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004372}
4373#endif /* HAVE_STATVFS */
4374
4375
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004376#ifdef HAVE_TEMPNAM
4377static char posix_tempnam__doc__[] = "\
4378tempnam([dir[, prefix]]) -> string\n\
4379Return a unique name for a temporary file.\n\
4380The directory and a short may be specified as strings; they may be omitted\n\
4381or None if not needed.";
4382
4383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004384posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004385{
4386 PyObject *result = NULL;
4387 char *dir = NULL;
4388 char *pfx = NULL;
4389 char *name;
4390
4391 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4392 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004393
4394 if (PyErr_Warn(PyExc_RuntimeWarning,
4395 "tempnam is a potential security risk to your program") < 0)
4396 return NULL;
4397
Fred Drake78b71c22001-07-17 20:37:36 +00004398#ifdef MS_WIN32
4399 name = _tempnam(dir, pfx);
4400#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004401 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004402#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004403 if (name == NULL)
4404 return PyErr_NoMemory();
4405 result = PyString_FromString(name);
4406 free(name);
4407 return result;
4408}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004409#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004410
4411
4412#ifdef HAVE_TMPFILE
4413static char posix_tmpfile__doc__[] = "\
4414tmpfile() -> file object\n\
4415Create a temporary file with no directory entries.";
4416
4417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004418posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004419{
4420 FILE *fp;
4421
4422 if (!PyArg_ParseTuple(args, ":tmpfile"))
4423 return NULL;
4424 fp = tmpfile();
4425 if (fp == NULL)
4426 return posix_error();
4427 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4428}
4429#endif
4430
4431
4432#ifdef HAVE_TMPNAM
4433static char posix_tmpnam__doc__[] = "\
4434tmpnam() -> string\n\
4435Return a unique name for a temporary file.";
4436
4437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004438posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004439{
4440 char buffer[L_tmpnam];
4441 char *name;
4442
4443 if (!PyArg_ParseTuple(args, ":tmpnam"))
4444 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004445
4446 if (PyErr_Warn(PyExc_RuntimeWarning,
4447 "tmpnam is a potential security risk to your program") < 0)
4448 return NULL;
4449
Greg Wardb48bc172000-03-01 21:51:56 +00004450#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004451 name = tmpnam_r(buffer);
4452#else
4453 name = tmpnam(buffer);
4454#endif
4455 if (name == NULL) {
4456 PyErr_SetObject(PyExc_OSError,
4457 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004458#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004459 "unexpected NULL from tmpnam_r"
4460#else
4461 "unexpected NULL from tmpnam"
4462#endif
4463 ));
4464 return NULL;
4465 }
4466 return PyString_FromString(buffer);
4467}
4468#endif
4469
4470
Fred Drakec9680921999-12-13 16:37:25 +00004471/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4472 * It maps strings representing configuration variable names to
4473 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004474 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004475 * rarely-used constants. There are three separate tables that use
4476 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004477 *
4478 * This code is always included, even if none of the interfaces that
4479 * need it are included. The #if hackery needed to avoid it would be
4480 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004481 */
4482struct constdef {
4483 char *name;
4484 long value;
4485};
4486
Fred Drake12c6e2d1999-12-14 21:25:03 +00004487static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004488conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4489 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004490{
4491 if (PyInt_Check(arg)) {
4492 *valuep = PyInt_AS_LONG(arg);
4493 return 1;
4494 }
4495 if (PyString_Check(arg)) {
4496 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004497 size_t lo = 0;
4498 size_t mid;
4499 size_t hi = tablesize;
4500 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004501 char *confname = PyString_AS_STRING(arg);
4502 while (lo < hi) {
4503 mid = (lo + hi) / 2;
4504 cmp = strcmp(confname, table[mid].name);
4505 if (cmp < 0)
4506 hi = mid;
4507 else if (cmp > 0)
4508 lo = mid + 1;
4509 else {
4510 *valuep = table[mid].value;
4511 return 1;
4512 }
4513 }
4514 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4515 }
4516 else
4517 PyErr_SetString(PyExc_TypeError,
4518 "configuration names must be strings or integers");
4519 return 0;
4520}
4521
4522
4523#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4524static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004525#ifdef _PC_ABI_AIO_XFER_MAX
4526 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4527#endif
4528#ifdef _PC_ABI_ASYNC_IO
4529 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4530#endif
Fred Drakec9680921999-12-13 16:37:25 +00004531#ifdef _PC_ASYNC_IO
4532 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4533#endif
4534#ifdef _PC_CHOWN_RESTRICTED
4535 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4536#endif
4537#ifdef _PC_FILESIZEBITS
4538 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4539#endif
4540#ifdef _PC_LAST
4541 {"PC_LAST", _PC_LAST},
4542#endif
4543#ifdef _PC_LINK_MAX
4544 {"PC_LINK_MAX", _PC_LINK_MAX},
4545#endif
4546#ifdef _PC_MAX_CANON
4547 {"PC_MAX_CANON", _PC_MAX_CANON},
4548#endif
4549#ifdef _PC_MAX_INPUT
4550 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4551#endif
4552#ifdef _PC_NAME_MAX
4553 {"PC_NAME_MAX", _PC_NAME_MAX},
4554#endif
4555#ifdef _PC_NO_TRUNC
4556 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4557#endif
4558#ifdef _PC_PATH_MAX
4559 {"PC_PATH_MAX", _PC_PATH_MAX},
4560#endif
4561#ifdef _PC_PIPE_BUF
4562 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4563#endif
4564#ifdef _PC_PRIO_IO
4565 {"PC_PRIO_IO", _PC_PRIO_IO},
4566#endif
4567#ifdef _PC_SOCK_MAXBUF
4568 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4569#endif
4570#ifdef _PC_SYNC_IO
4571 {"PC_SYNC_IO", _PC_SYNC_IO},
4572#endif
4573#ifdef _PC_VDISABLE
4574 {"PC_VDISABLE", _PC_VDISABLE},
4575#endif
4576};
4577
Fred Drakec9680921999-12-13 16:37:25 +00004578static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004579conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004580{
4581 return conv_confname(arg, valuep, posix_constants_pathconf,
4582 sizeof(posix_constants_pathconf)
4583 / sizeof(struct constdef));
4584}
4585#endif
4586
4587#ifdef HAVE_FPATHCONF
4588static char posix_fpathconf__doc__[] = "\
4589fpathconf(fd, name) -> integer\n\
4590Return the configuration limit name for the file descriptor fd.\n\
4591If there is no limit, return -1.";
4592
4593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004594posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004595{
4596 PyObject *result = NULL;
4597 int name, fd;
4598
Fred Drake12c6e2d1999-12-14 21:25:03 +00004599 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4600 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004601 long limit;
4602
4603 errno = 0;
4604 limit = fpathconf(fd, name);
4605 if (limit == -1 && errno != 0)
4606 posix_error();
4607 else
4608 result = PyInt_FromLong(limit);
4609 }
4610 return result;
4611}
4612#endif
4613
4614
4615#ifdef HAVE_PATHCONF
4616static char posix_pathconf__doc__[] = "\
4617pathconf(path, name) -> integer\n\
4618Return the configuration limit name for the file or directory path.\n\
4619If there is no limit, return -1.";
4620
4621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004622posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004623{
4624 PyObject *result = NULL;
4625 int name;
4626 char *path;
4627
4628 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4629 conv_path_confname, &name)) {
4630 long limit;
4631
4632 errno = 0;
4633 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004634 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004635 if (errno == EINVAL)
4636 /* could be a path or name problem */
4637 posix_error();
4638 else
4639 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004640 }
Fred Drakec9680921999-12-13 16:37:25 +00004641 else
4642 result = PyInt_FromLong(limit);
4643 }
4644 return result;
4645}
4646#endif
4647
4648#ifdef HAVE_CONFSTR
4649static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004650#ifdef _CS_ARCHITECTURE
4651 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4652#endif
4653#ifdef _CS_HOSTNAME
4654 {"CS_HOSTNAME", _CS_HOSTNAME},
4655#endif
4656#ifdef _CS_HW_PROVIDER
4657 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4658#endif
4659#ifdef _CS_HW_SERIAL
4660 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4661#endif
4662#ifdef _CS_INITTAB_NAME
4663 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4664#endif
Fred Drakec9680921999-12-13 16:37:25 +00004665#ifdef _CS_LFS64_CFLAGS
4666 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4667#endif
4668#ifdef _CS_LFS64_LDFLAGS
4669 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4670#endif
4671#ifdef _CS_LFS64_LIBS
4672 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4673#endif
4674#ifdef _CS_LFS64_LINTFLAGS
4675 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4676#endif
4677#ifdef _CS_LFS_CFLAGS
4678 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4679#endif
4680#ifdef _CS_LFS_LDFLAGS
4681 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4682#endif
4683#ifdef _CS_LFS_LIBS
4684 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4685#endif
4686#ifdef _CS_LFS_LINTFLAGS
4687 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4688#endif
Fred Draked86ed291999-12-15 15:34:33 +00004689#ifdef _CS_MACHINE
4690 {"CS_MACHINE", _CS_MACHINE},
4691#endif
Fred Drakec9680921999-12-13 16:37:25 +00004692#ifdef _CS_PATH
4693 {"CS_PATH", _CS_PATH},
4694#endif
Fred Draked86ed291999-12-15 15:34:33 +00004695#ifdef _CS_RELEASE
4696 {"CS_RELEASE", _CS_RELEASE},
4697#endif
4698#ifdef _CS_SRPC_DOMAIN
4699 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4700#endif
4701#ifdef _CS_SYSNAME
4702 {"CS_SYSNAME", _CS_SYSNAME},
4703#endif
4704#ifdef _CS_VERSION
4705 {"CS_VERSION", _CS_VERSION},
4706#endif
Fred Drakec9680921999-12-13 16:37:25 +00004707#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4708 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4709#endif
4710#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4711 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4712#endif
4713#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4714 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4715#endif
4716#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4717 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4718#endif
4719#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4720 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4721#endif
4722#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4723 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4724#endif
4725#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4726 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4727#endif
4728#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4729 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4730#endif
4731#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4732 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4733#endif
4734#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4735 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4736#endif
4737#ifdef _CS_XBS5_LP64_OFF64_LIBS
4738 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4739#endif
4740#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4741 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4742#endif
4743#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4744 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4745#endif
4746#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4747 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4748#endif
4749#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4750 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4751#endif
4752#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4753 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4754#endif
Fred Draked86ed291999-12-15 15:34:33 +00004755#ifdef _MIPS_CS_AVAIL_PROCESSORS
4756 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4757#endif
4758#ifdef _MIPS_CS_BASE
4759 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4760#endif
4761#ifdef _MIPS_CS_HOSTID
4762 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4763#endif
4764#ifdef _MIPS_CS_HW_NAME
4765 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4766#endif
4767#ifdef _MIPS_CS_NUM_PROCESSORS
4768 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4769#endif
4770#ifdef _MIPS_CS_OSREL_MAJ
4771 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4772#endif
4773#ifdef _MIPS_CS_OSREL_MIN
4774 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4775#endif
4776#ifdef _MIPS_CS_OSREL_PATCH
4777 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4778#endif
4779#ifdef _MIPS_CS_OS_NAME
4780 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4781#endif
4782#ifdef _MIPS_CS_OS_PROVIDER
4783 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4784#endif
4785#ifdef _MIPS_CS_PROCESSORS
4786 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4787#endif
4788#ifdef _MIPS_CS_SERIAL
4789 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4790#endif
4791#ifdef _MIPS_CS_VENDOR
4792 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4793#endif
Fred Drakec9680921999-12-13 16:37:25 +00004794};
4795
4796static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004797conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004798{
4799 return conv_confname(arg, valuep, posix_constants_confstr,
4800 sizeof(posix_constants_confstr)
4801 / sizeof(struct constdef));
4802}
4803
4804static char posix_confstr__doc__[] = "\
4805confstr(name) -> string\n\
4806Return a string-valued system configuration variable.";
4807
4808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004809posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004810{
4811 PyObject *result = NULL;
4812 int name;
4813 char buffer[64];
4814
4815 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4816 int len = confstr(name, buffer, sizeof(buffer));
4817
Fred Drakec9680921999-12-13 16:37:25 +00004818 errno = 0;
4819 if (len == 0) {
4820 if (errno != 0)
4821 posix_error();
4822 else
4823 result = PyString_FromString("");
4824 }
4825 else {
4826 if (len >= sizeof(buffer)) {
4827 result = PyString_FromStringAndSize(NULL, len);
4828 if (result != NULL)
4829 confstr(name, PyString_AS_STRING(result), len+1);
4830 }
4831 else
4832 result = PyString_FromString(buffer);
4833 }
4834 }
4835 return result;
4836}
4837#endif
4838
4839
4840#ifdef HAVE_SYSCONF
4841static struct constdef posix_constants_sysconf[] = {
4842#ifdef _SC_2_CHAR_TERM
4843 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4844#endif
4845#ifdef _SC_2_C_BIND
4846 {"SC_2_C_BIND", _SC_2_C_BIND},
4847#endif
4848#ifdef _SC_2_C_DEV
4849 {"SC_2_C_DEV", _SC_2_C_DEV},
4850#endif
4851#ifdef _SC_2_C_VERSION
4852 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4853#endif
4854#ifdef _SC_2_FORT_DEV
4855 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4856#endif
4857#ifdef _SC_2_FORT_RUN
4858 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4859#endif
4860#ifdef _SC_2_LOCALEDEF
4861 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4862#endif
4863#ifdef _SC_2_SW_DEV
4864 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4865#endif
4866#ifdef _SC_2_UPE
4867 {"SC_2_UPE", _SC_2_UPE},
4868#endif
4869#ifdef _SC_2_VERSION
4870 {"SC_2_VERSION", _SC_2_VERSION},
4871#endif
Fred Draked86ed291999-12-15 15:34:33 +00004872#ifdef _SC_ABI_ASYNCHRONOUS_IO
4873 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4874#endif
4875#ifdef _SC_ACL
4876 {"SC_ACL", _SC_ACL},
4877#endif
Fred Drakec9680921999-12-13 16:37:25 +00004878#ifdef _SC_AIO_LISTIO_MAX
4879 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4880#endif
Fred Drakec9680921999-12-13 16:37:25 +00004881#ifdef _SC_AIO_MAX
4882 {"SC_AIO_MAX", _SC_AIO_MAX},
4883#endif
4884#ifdef _SC_AIO_PRIO_DELTA_MAX
4885 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4886#endif
4887#ifdef _SC_ARG_MAX
4888 {"SC_ARG_MAX", _SC_ARG_MAX},
4889#endif
4890#ifdef _SC_ASYNCHRONOUS_IO
4891 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4892#endif
4893#ifdef _SC_ATEXIT_MAX
4894 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4895#endif
Fred Draked86ed291999-12-15 15:34:33 +00004896#ifdef _SC_AUDIT
4897 {"SC_AUDIT", _SC_AUDIT},
4898#endif
Fred Drakec9680921999-12-13 16:37:25 +00004899#ifdef _SC_AVPHYS_PAGES
4900 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4901#endif
4902#ifdef _SC_BC_BASE_MAX
4903 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4904#endif
4905#ifdef _SC_BC_DIM_MAX
4906 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4907#endif
4908#ifdef _SC_BC_SCALE_MAX
4909 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4910#endif
4911#ifdef _SC_BC_STRING_MAX
4912 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4913#endif
Fred Draked86ed291999-12-15 15:34:33 +00004914#ifdef _SC_CAP
4915 {"SC_CAP", _SC_CAP},
4916#endif
Fred Drakec9680921999-12-13 16:37:25 +00004917#ifdef _SC_CHARCLASS_NAME_MAX
4918 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4919#endif
4920#ifdef _SC_CHAR_BIT
4921 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4922#endif
4923#ifdef _SC_CHAR_MAX
4924 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4925#endif
4926#ifdef _SC_CHAR_MIN
4927 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4928#endif
4929#ifdef _SC_CHILD_MAX
4930 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4931#endif
4932#ifdef _SC_CLK_TCK
4933 {"SC_CLK_TCK", _SC_CLK_TCK},
4934#endif
4935#ifdef _SC_COHER_BLKSZ
4936 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4937#endif
4938#ifdef _SC_COLL_WEIGHTS_MAX
4939 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4940#endif
4941#ifdef _SC_DCACHE_ASSOC
4942 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4943#endif
4944#ifdef _SC_DCACHE_BLKSZ
4945 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4946#endif
4947#ifdef _SC_DCACHE_LINESZ
4948 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4949#endif
4950#ifdef _SC_DCACHE_SZ
4951 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4952#endif
4953#ifdef _SC_DCACHE_TBLKSZ
4954 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4955#endif
4956#ifdef _SC_DELAYTIMER_MAX
4957 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4958#endif
4959#ifdef _SC_EQUIV_CLASS_MAX
4960 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4961#endif
4962#ifdef _SC_EXPR_NEST_MAX
4963 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4964#endif
4965#ifdef _SC_FSYNC
4966 {"SC_FSYNC", _SC_FSYNC},
4967#endif
4968#ifdef _SC_GETGR_R_SIZE_MAX
4969 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4970#endif
4971#ifdef _SC_GETPW_R_SIZE_MAX
4972 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4973#endif
4974#ifdef _SC_ICACHE_ASSOC
4975 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4976#endif
4977#ifdef _SC_ICACHE_BLKSZ
4978 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4979#endif
4980#ifdef _SC_ICACHE_LINESZ
4981 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4982#endif
4983#ifdef _SC_ICACHE_SZ
4984 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4985#endif
Fred Draked86ed291999-12-15 15:34:33 +00004986#ifdef _SC_INF
4987 {"SC_INF", _SC_INF},
4988#endif
Fred Drakec9680921999-12-13 16:37:25 +00004989#ifdef _SC_INT_MAX
4990 {"SC_INT_MAX", _SC_INT_MAX},
4991#endif
4992#ifdef _SC_INT_MIN
4993 {"SC_INT_MIN", _SC_INT_MIN},
4994#endif
4995#ifdef _SC_IOV_MAX
4996 {"SC_IOV_MAX", _SC_IOV_MAX},
4997#endif
Fred Draked86ed291999-12-15 15:34:33 +00004998#ifdef _SC_IP_SECOPTS
4999 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5000#endif
Fred Drakec9680921999-12-13 16:37:25 +00005001#ifdef _SC_JOB_CONTROL
5002 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5003#endif
Fred Draked86ed291999-12-15 15:34:33 +00005004#ifdef _SC_KERN_POINTERS
5005 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5006#endif
5007#ifdef _SC_KERN_SIM
5008 {"SC_KERN_SIM", _SC_KERN_SIM},
5009#endif
Fred Drakec9680921999-12-13 16:37:25 +00005010#ifdef _SC_LINE_MAX
5011 {"SC_LINE_MAX", _SC_LINE_MAX},
5012#endif
5013#ifdef _SC_LOGIN_NAME_MAX
5014 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5015#endif
5016#ifdef _SC_LOGNAME_MAX
5017 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5018#endif
5019#ifdef _SC_LONG_BIT
5020 {"SC_LONG_BIT", _SC_LONG_BIT},
5021#endif
Fred Draked86ed291999-12-15 15:34:33 +00005022#ifdef _SC_MAC
5023 {"SC_MAC", _SC_MAC},
5024#endif
Fred Drakec9680921999-12-13 16:37:25 +00005025#ifdef _SC_MAPPED_FILES
5026 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5027#endif
5028#ifdef _SC_MAXPID
5029 {"SC_MAXPID", _SC_MAXPID},
5030#endif
5031#ifdef _SC_MB_LEN_MAX
5032 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5033#endif
5034#ifdef _SC_MEMLOCK
5035 {"SC_MEMLOCK", _SC_MEMLOCK},
5036#endif
5037#ifdef _SC_MEMLOCK_RANGE
5038 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5039#endif
5040#ifdef _SC_MEMORY_PROTECTION
5041 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5042#endif
5043#ifdef _SC_MESSAGE_PASSING
5044 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5045#endif
Fred Draked86ed291999-12-15 15:34:33 +00005046#ifdef _SC_MMAP_FIXED_ALIGNMENT
5047 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5048#endif
Fred Drakec9680921999-12-13 16:37:25 +00005049#ifdef _SC_MQ_OPEN_MAX
5050 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5051#endif
5052#ifdef _SC_MQ_PRIO_MAX
5053 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5054#endif
Fred Draked86ed291999-12-15 15:34:33 +00005055#ifdef _SC_NACLS_MAX
5056 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5057#endif
Fred Drakec9680921999-12-13 16:37:25 +00005058#ifdef _SC_NGROUPS_MAX
5059 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5060#endif
5061#ifdef _SC_NL_ARGMAX
5062 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5063#endif
5064#ifdef _SC_NL_LANGMAX
5065 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5066#endif
5067#ifdef _SC_NL_MSGMAX
5068 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5069#endif
5070#ifdef _SC_NL_NMAX
5071 {"SC_NL_NMAX", _SC_NL_NMAX},
5072#endif
5073#ifdef _SC_NL_SETMAX
5074 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5075#endif
5076#ifdef _SC_NL_TEXTMAX
5077 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5078#endif
5079#ifdef _SC_NPROCESSORS_CONF
5080 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5081#endif
5082#ifdef _SC_NPROCESSORS_ONLN
5083 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5084#endif
Fred Draked86ed291999-12-15 15:34:33 +00005085#ifdef _SC_NPROC_CONF
5086 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5087#endif
5088#ifdef _SC_NPROC_ONLN
5089 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5090#endif
Fred Drakec9680921999-12-13 16:37:25 +00005091#ifdef _SC_NZERO
5092 {"SC_NZERO", _SC_NZERO},
5093#endif
5094#ifdef _SC_OPEN_MAX
5095 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5096#endif
5097#ifdef _SC_PAGESIZE
5098 {"SC_PAGESIZE", _SC_PAGESIZE},
5099#endif
5100#ifdef _SC_PAGE_SIZE
5101 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5102#endif
5103#ifdef _SC_PASS_MAX
5104 {"SC_PASS_MAX", _SC_PASS_MAX},
5105#endif
5106#ifdef _SC_PHYS_PAGES
5107 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5108#endif
5109#ifdef _SC_PII
5110 {"SC_PII", _SC_PII},
5111#endif
5112#ifdef _SC_PII_INTERNET
5113 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5114#endif
5115#ifdef _SC_PII_INTERNET_DGRAM
5116 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5117#endif
5118#ifdef _SC_PII_INTERNET_STREAM
5119 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5120#endif
5121#ifdef _SC_PII_OSI
5122 {"SC_PII_OSI", _SC_PII_OSI},
5123#endif
5124#ifdef _SC_PII_OSI_CLTS
5125 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5126#endif
5127#ifdef _SC_PII_OSI_COTS
5128 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5129#endif
5130#ifdef _SC_PII_OSI_M
5131 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5132#endif
5133#ifdef _SC_PII_SOCKET
5134 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5135#endif
5136#ifdef _SC_PII_XTI
5137 {"SC_PII_XTI", _SC_PII_XTI},
5138#endif
5139#ifdef _SC_POLL
5140 {"SC_POLL", _SC_POLL},
5141#endif
5142#ifdef _SC_PRIORITIZED_IO
5143 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5144#endif
5145#ifdef _SC_PRIORITY_SCHEDULING
5146 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5147#endif
5148#ifdef _SC_REALTIME_SIGNALS
5149 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5150#endif
5151#ifdef _SC_RE_DUP_MAX
5152 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5153#endif
5154#ifdef _SC_RTSIG_MAX
5155 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5156#endif
5157#ifdef _SC_SAVED_IDS
5158 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5159#endif
5160#ifdef _SC_SCHAR_MAX
5161 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5162#endif
5163#ifdef _SC_SCHAR_MIN
5164 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5165#endif
5166#ifdef _SC_SELECT
5167 {"SC_SELECT", _SC_SELECT},
5168#endif
5169#ifdef _SC_SEMAPHORES
5170 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5171#endif
5172#ifdef _SC_SEM_NSEMS_MAX
5173 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5174#endif
5175#ifdef _SC_SEM_VALUE_MAX
5176 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5177#endif
5178#ifdef _SC_SHARED_MEMORY_OBJECTS
5179 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5180#endif
5181#ifdef _SC_SHRT_MAX
5182 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5183#endif
5184#ifdef _SC_SHRT_MIN
5185 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5186#endif
5187#ifdef _SC_SIGQUEUE_MAX
5188 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5189#endif
5190#ifdef _SC_SIGRT_MAX
5191 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5192#endif
5193#ifdef _SC_SIGRT_MIN
5194 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5195#endif
Fred Draked86ed291999-12-15 15:34:33 +00005196#ifdef _SC_SOFTPOWER
5197 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5198#endif
Fred Drakec9680921999-12-13 16:37:25 +00005199#ifdef _SC_SPLIT_CACHE
5200 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5201#endif
5202#ifdef _SC_SSIZE_MAX
5203 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5204#endif
5205#ifdef _SC_STACK_PROT
5206 {"SC_STACK_PROT", _SC_STACK_PROT},
5207#endif
5208#ifdef _SC_STREAM_MAX
5209 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5210#endif
5211#ifdef _SC_SYNCHRONIZED_IO
5212 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5213#endif
5214#ifdef _SC_THREADS
5215 {"SC_THREADS", _SC_THREADS},
5216#endif
5217#ifdef _SC_THREAD_ATTR_STACKADDR
5218 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5219#endif
5220#ifdef _SC_THREAD_ATTR_STACKSIZE
5221 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5222#endif
5223#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5224 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5225#endif
5226#ifdef _SC_THREAD_KEYS_MAX
5227 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5228#endif
5229#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5230 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5231#endif
5232#ifdef _SC_THREAD_PRIO_INHERIT
5233 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5234#endif
5235#ifdef _SC_THREAD_PRIO_PROTECT
5236 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5237#endif
5238#ifdef _SC_THREAD_PROCESS_SHARED
5239 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5240#endif
5241#ifdef _SC_THREAD_SAFE_FUNCTIONS
5242 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5243#endif
5244#ifdef _SC_THREAD_STACK_MIN
5245 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5246#endif
5247#ifdef _SC_THREAD_THREADS_MAX
5248 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5249#endif
5250#ifdef _SC_TIMERS
5251 {"SC_TIMERS", _SC_TIMERS},
5252#endif
5253#ifdef _SC_TIMER_MAX
5254 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5255#endif
5256#ifdef _SC_TTY_NAME_MAX
5257 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5258#endif
5259#ifdef _SC_TZNAME_MAX
5260 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5261#endif
5262#ifdef _SC_T_IOV_MAX
5263 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5264#endif
5265#ifdef _SC_UCHAR_MAX
5266 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5267#endif
5268#ifdef _SC_UINT_MAX
5269 {"SC_UINT_MAX", _SC_UINT_MAX},
5270#endif
5271#ifdef _SC_UIO_MAXIOV
5272 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5273#endif
5274#ifdef _SC_ULONG_MAX
5275 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5276#endif
5277#ifdef _SC_USHRT_MAX
5278 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5279#endif
5280#ifdef _SC_VERSION
5281 {"SC_VERSION", _SC_VERSION},
5282#endif
5283#ifdef _SC_WORD_BIT
5284 {"SC_WORD_BIT", _SC_WORD_BIT},
5285#endif
5286#ifdef _SC_XBS5_ILP32_OFF32
5287 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5288#endif
5289#ifdef _SC_XBS5_ILP32_OFFBIG
5290 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5291#endif
5292#ifdef _SC_XBS5_LP64_OFF64
5293 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5294#endif
5295#ifdef _SC_XBS5_LPBIG_OFFBIG
5296 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5297#endif
5298#ifdef _SC_XOPEN_CRYPT
5299 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5300#endif
5301#ifdef _SC_XOPEN_ENH_I18N
5302 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5303#endif
5304#ifdef _SC_XOPEN_LEGACY
5305 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5306#endif
5307#ifdef _SC_XOPEN_REALTIME
5308 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5309#endif
5310#ifdef _SC_XOPEN_REALTIME_THREADS
5311 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5312#endif
5313#ifdef _SC_XOPEN_SHM
5314 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5315#endif
5316#ifdef _SC_XOPEN_UNIX
5317 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5318#endif
5319#ifdef _SC_XOPEN_VERSION
5320 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5321#endif
5322#ifdef _SC_XOPEN_XCU_VERSION
5323 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5324#endif
5325#ifdef _SC_XOPEN_XPG2
5326 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5327#endif
5328#ifdef _SC_XOPEN_XPG3
5329 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5330#endif
5331#ifdef _SC_XOPEN_XPG4
5332 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5333#endif
5334};
5335
5336static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005337conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005338{
5339 return conv_confname(arg, valuep, posix_constants_sysconf,
5340 sizeof(posix_constants_sysconf)
5341 / sizeof(struct constdef));
5342}
5343
5344static char posix_sysconf__doc__[] = "\
5345sysconf(name) -> integer\n\
5346Return an integer-valued system configuration variable.";
5347
5348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005349posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005350{
5351 PyObject *result = NULL;
5352 int name;
5353
5354 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5355 int value;
5356
5357 errno = 0;
5358 value = sysconf(name);
5359 if (value == -1 && errno != 0)
5360 posix_error();
5361 else
5362 result = PyInt_FromLong(value);
5363 }
5364 return result;
5365}
5366#endif
5367
5368
Fred Drakebec628d1999-12-15 18:31:10 +00005369/* This code is used to ensure that the tables of configuration value names
5370 * are in sorted order as required by conv_confname(), and also to build the
5371 * the exported dictionaries that are used to publish information about the
5372 * names available on the host platform.
5373 *
5374 * Sorting the table at runtime ensures that the table is properly ordered
5375 * when used, even for platforms we're not able to test on. It also makes
5376 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005377 */
Fred Drakebec628d1999-12-15 18:31:10 +00005378
5379static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005380cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005381{
5382 const struct constdef *c1 =
5383 (const struct constdef *) v1;
5384 const struct constdef *c2 =
5385 (const struct constdef *) v2;
5386
5387 return strcmp(c1->name, c2->name);
5388}
5389
5390static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005391setup_confname_table(struct constdef *table, size_t tablesize,
5392 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005393{
Fred Drakebec628d1999-12-15 18:31:10 +00005394 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005395 size_t i;
5396 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005397
5398 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5399 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005400 if (d == NULL)
5401 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005402
Barry Warsaw3155db32000-04-13 15:20:40 +00005403 for (i=0; i < tablesize; ++i) {
5404 PyObject *o = PyInt_FromLong(table[i].value);
5405 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5406 Py_XDECREF(o);
5407 Py_DECREF(d);
5408 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005409 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005410 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005411 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005412 status = PyDict_SetItemString(moddict, tablename, d);
5413 Py_DECREF(d);
5414 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005415}
5416
Fred Drakebec628d1999-12-15 18:31:10 +00005417/* Return -1 on failure, 0 on success. */
5418static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005419setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005420{
5421#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005422 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005423 sizeof(posix_constants_pathconf)
5424 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005425 "pathconf_names", moddict))
5426 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005427#endif
5428#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005429 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005430 sizeof(posix_constants_confstr)
5431 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005432 "confstr_names", moddict))
5433 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005434#endif
5435#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005436 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005437 sizeof(posix_constants_sysconf)
5438 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005439 "sysconf_names", moddict))
5440 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005441#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005442 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005443}
Fred Draked86ed291999-12-15 15:34:33 +00005444
5445
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005446static char posix_abort__doc__[] = "\
5447abort() -> does not return!\n\
5448Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5449in the hardest way possible on the hosting operating system.";
5450
5451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005452posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005453{
5454 if (!PyArg_ParseTuple(args, ":abort"))
5455 return NULL;
5456 abort();
5457 /*NOTREACHED*/
5458 Py_FatalError("abort() called from Python code didn't abort!");
5459 return NULL;
5460}
Fred Drakebec628d1999-12-15 18:31:10 +00005461
Tim Petersf58a7aa2000-09-22 10:05:54 +00005462#ifdef MS_WIN32
5463static char win32_startfile__doc__[] = "\
5464startfile(filepath) - Start a file with its associated application.\n\
5465\n\
5466This acts like double-clicking the file in Explorer, or giving the file\n\
5467name as an argument to the DOS \"start\" command: the file is opened\n\
5468with whatever application (if any) its extension is associated.\n\
5469\n\
5470startfile returns as soon as the associated application is launched.\n\
5471There is no option to wait for the application to close, and no way\n\
5472to retrieve the application's exit status.\n\
5473\n\
5474The filepath is relative to the current directory. If you want to use\n\
5475an absolute path, make sure the first character is not a slash (\"/\");\n\
5476the underlying Win32 ShellExecute function doesn't work if it is.";
5477
5478static PyObject *
5479win32_startfile(PyObject *self, PyObject *args)
5480{
5481 char *filepath;
5482 HINSTANCE rc;
5483 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5484 return NULL;
5485 Py_BEGIN_ALLOW_THREADS
5486 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5487 Py_END_ALLOW_THREADS
5488 if (rc <= (HINSTANCE)32)
5489 return win32_error("startfile", filepath);
5490 Py_INCREF(Py_None);
5491 return Py_None;
5492}
5493#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005494
5495static PyMethodDef posix_methods[] = {
5496 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5497#ifdef HAVE_TTYNAME
5498 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5499#endif
5500 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5501 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005502#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005503 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005504#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005505#ifdef HAVE_CHROOT
5506 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5507#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005508#ifdef HAVE_CTERMID
5509 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5510#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005511#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005512 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005513#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005514#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005515 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005516#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005517 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5518 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5519 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005520#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005521 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005522#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005523#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005524 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005525#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005526 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5527 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5528 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005529#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005530 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005531#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005532#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005533 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005534#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005535 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005536#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005537 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005538#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005539 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5540 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5541 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005542#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005543 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005544#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005545 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005546#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005547 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5548 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005549#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005550#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005551 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5552 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005553#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005554#ifdef HAVE_FORK1
5555 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5556#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005557#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005558 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005559#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005560#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005561 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005562#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005563#ifdef HAVE_FORKPTY
5564 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5565#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005566#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005567 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005568#endif /* HAVE_GETEGID */
5569#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005570 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005571#endif /* HAVE_GETEUID */
5572#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005573 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005574#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005575#ifdef HAVE_GETGROUPS
5576 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5577#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005578 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005579#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005580 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005581#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005582#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005583 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005584#endif /* HAVE_GETPPID */
5585#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005586 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005587#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005588#ifdef HAVE_GETLOGIN
5589 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5590#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005591#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005592 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005593#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005594#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005595 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005596#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005597#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005598 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005599#ifdef MS_WIN32
5600 {"popen2", win32_popen2, METH_VARARGS},
5601 {"popen3", win32_popen3, METH_VARARGS},
5602 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005603 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005604#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005605#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005606#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005607 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005608#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005609#ifdef HAVE_SETEUID
5610 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5611#endif /* HAVE_SETEUID */
5612#ifdef HAVE_SETEGID
5613 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5614#endif /* HAVE_SETEGID */
5615#ifdef HAVE_SETREUID
5616 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5617#endif /* HAVE_SETREUID */
5618#ifdef HAVE_SETREGID
5619 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5620#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005621#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005622 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005623#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005624#ifdef HAVE_SETGROUPS
5625 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5626#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005627#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005628 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005629#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005630#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005631 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005632#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005633#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005634 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005635#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005636#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005637 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005638#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005639#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005640 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005641#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005642#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005643 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005644#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005645#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005646 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005647#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005648 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5649 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5650 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5651 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5652 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5653 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5654 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5655 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5656 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005657 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005658#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005659 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005660#endif
5661#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005662 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005663#endif
5664#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005665 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005666#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005667#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005668 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005669#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005670#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005671 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005672#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005673#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005674 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005675#endif
5676#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005677 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005678#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005679#ifdef HAVE_SYS_WAIT_H
5680#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005681 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005682#endif /* WIFSTOPPED */
5683#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005684 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005685#endif /* WIFSIGNALED */
5686#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005687 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005688#endif /* WIFEXITED */
5689#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005690 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005691#endif /* WEXITSTATUS */
5692#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005693 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005694#endif /* WTERMSIG */
5695#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005696 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005697#endif /* WSTOPSIG */
5698#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005699#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005700 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005701#endif
5702#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005703 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005704#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005705#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005706 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5707#endif
5708#ifdef HAVE_TEMPNAM
5709 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5710#endif
5711#ifdef HAVE_TMPNAM
5712 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5713#endif
Fred Drakec9680921999-12-13 16:37:25 +00005714#ifdef HAVE_CONFSTR
5715 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5716#endif
5717#ifdef HAVE_SYSCONF
5718 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5719#endif
5720#ifdef HAVE_FPATHCONF
5721 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5722#endif
5723#ifdef HAVE_PATHCONF
5724 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5725#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005726 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005727#ifdef MS_WIN32
5728 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5729#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005730 {NULL, NULL} /* Sentinel */
5731};
5732
5733
Barry Warsaw4a342091996-12-19 23:50:02 +00005734static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005735ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005736{
5737 PyObject* v = PyInt_FromLong(value);
5738 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5739 return -1; /* triggers fatal error */
5740
5741 Py_DECREF(v);
5742 return 0;
5743}
5744
Guido van Rossumd48f2521997-12-05 22:19:34 +00005745#if defined(PYOS_OS2)
5746/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5747static int insertvalues(PyObject *d)
5748{
5749 APIRET rc;
5750 ULONG values[QSV_MAX+1];
5751 PyObject *v;
5752 char *ver, tmp[10];
5753
5754 Py_BEGIN_ALLOW_THREADS
5755 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5756 Py_END_ALLOW_THREADS
5757
5758 if (rc != NO_ERROR) {
5759 os2_error(rc);
5760 return -1;
5761 }
5762
5763 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5764 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5765 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5766 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5767 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5768 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5769 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5770
5771 switch (values[QSV_VERSION_MINOR]) {
5772 case 0: ver = "2.00"; break;
5773 case 10: ver = "2.10"; break;
5774 case 11: ver = "2.11"; break;
5775 case 30: ver = "3.00"; break;
5776 case 40: ver = "4.00"; break;
5777 case 50: ver = "5.00"; break;
5778 default:
5779 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5780 values[QSV_VERSION_MINOR]);
5781 ver = &tmp[0];
5782 }
5783
5784 /* Add Indicator of the Version of the Operating System */
5785 v = PyString_FromString(ver);
5786 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5787 return -1;
5788 Py_DECREF(v);
5789
5790 /* Add Indicator of Which Drive was Used to Boot the System */
5791 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5792 tmp[1] = ':';
5793 tmp[2] = '\0';
5794
5795 v = PyString_FromString(tmp);
5796 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5797 return -1;
5798 Py_DECREF(v);
5799
5800 return 0;
5801}
5802#endif
5803
Barry Warsaw4a342091996-12-19 23:50:02 +00005804static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005805all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005806{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005807#ifdef F_OK
5808 if (ins(d, "F_OK", (long)F_OK)) return -1;
5809#endif
5810#ifdef R_OK
5811 if (ins(d, "R_OK", (long)R_OK)) return -1;
5812#endif
5813#ifdef W_OK
5814 if (ins(d, "W_OK", (long)W_OK)) return -1;
5815#endif
5816#ifdef X_OK
5817 if (ins(d, "X_OK", (long)X_OK)) return -1;
5818#endif
Fred Drakec9680921999-12-13 16:37:25 +00005819#ifdef NGROUPS_MAX
5820 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5821#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005822#ifdef TMP_MAX
5823 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5824#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005825#ifdef WNOHANG
5826 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5827#endif
5828#ifdef O_RDONLY
5829 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5830#endif
5831#ifdef O_WRONLY
5832 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5833#endif
5834#ifdef O_RDWR
5835 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5836#endif
5837#ifdef O_NDELAY
5838 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5839#endif
5840#ifdef O_NONBLOCK
5841 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5842#endif
5843#ifdef O_APPEND
5844 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5845#endif
5846#ifdef O_DSYNC
5847 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5848#endif
5849#ifdef O_RSYNC
5850 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5851#endif
5852#ifdef O_SYNC
5853 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5854#endif
5855#ifdef O_NOCTTY
5856 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5857#endif
5858#ifdef O_CREAT
5859 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5860#endif
5861#ifdef O_EXCL
5862 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5863#endif
5864#ifdef O_TRUNC
5865 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5866#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005867#ifdef O_BINARY
5868 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5869#endif
5870#ifdef O_TEXT
5871 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5872#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005873
Guido van Rossum246bc171999-02-01 23:54:31 +00005874#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005875 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5876 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5877 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5878 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5879 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005880#endif
5881
Guido van Rossumd48f2521997-12-05 22:19:34 +00005882#if defined(PYOS_OS2)
5883 if (insertvalues(d)) return -1;
5884#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005885 return 0;
5886}
5887
5888
Tim Peters58e0a8c2001-05-14 22:32:33 +00005889#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005890#define INITFUNC initnt
5891#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005892
5893#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005894#define INITFUNC initos2
5895#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005896
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005897#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005898#define INITFUNC initposix
5899#define MODNAME "posix"
5900#endif
5901
Guido van Rossum3886bb61998-12-04 18:50:17 +00005902DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005903INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005904{
Barry Warsaw53699e91996-12-10 23:23:01 +00005905 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005906
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005907 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005908 posix_methods,
5909 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005910 (PyObject *)NULL,
5911 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005912 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005913
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005914 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005915 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005916 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005917 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005918 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005919
Barry Warsaw4a342091996-12-19 23:50:02 +00005920 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005921 return;
5922
Fred Drakebec628d1999-12-15 18:31:10 +00005923 if (setup_confname_tables(d))
5924 return;
5925
Barry Warsawca74da41999-02-09 19:31:45 +00005926 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005927
Guido van Rossumb3d39562000-01-31 18:41:26 +00005928#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005929 if (posix_putenv_garbage == NULL)
5930 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005931#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005932
5933 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
5934 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
5935
5936 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
5937 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005938}