blob: 365a8366d3cf15a966294bd7e5ecc985be4af0f8 [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
Tim Peters885d4572001-11-28 20:27:42 +0000435 PyOS_snprintf(msgbuf, sizeof(msgbuf),
436 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000437
438 return msgbuf;
439}
440
441/* Set an OS/2-specific error and return NULL. OS/2 kernel
442 errors are not in a global variable e.g. 'errno' nor are
443 they congruent with posix error numbers. */
444
445static PyObject * os2_error(int code)
446{
447 char text[1024];
448 PyObject *v;
449
450 os2_strerror(text, sizeof(text), code, "");
451
452 v = Py_BuildValue("(is)", code, text);
453 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000454 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000455 Py_DECREF(v);
456 }
457 return NULL; /* Signal to Python that an Exception is Pending */
458}
459
460#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461
462/* POSIX generic methods */
463
Barry Warsaw53699e91996-12-10 23:23:01 +0000464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000465posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000466{
467 int fd;
468 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000469 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000470 return NULL;
471 Py_BEGIN_ALLOW_THREADS
472 res = (*func)(fd);
473 Py_END_ALLOW_THREADS
474 if (res < 0)
475 return posix_error();
476 Py_INCREF(Py_None);
477 return Py_None;
478}
479
480
481static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000482posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483{
Mark Hammondef8b6542001-05-13 08:04:26 +0000484 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000486 if (!PyArg_ParseTuple(args, format,
487 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000489 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000491 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000492 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000493 return posix_error_with_allocated_filename(path1);
494 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000495 Py_INCREF(Py_None);
496 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497}
498
Barry Warsaw53699e91996-12-10 23:23:01 +0000499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000500posix_2str(PyObject *args, char *format,
501 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502{
Mark Hammondef8b6542001-05-13 08:04:26 +0000503 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000504 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000505 if (!PyArg_ParseTuple(args, format,
506 Py_FileSystemDefaultEncoding, &path1,
507 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000509 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000510 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000511 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000512 PyMem_Free(path1);
513 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000514 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000515 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000516 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000517 Py_INCREF(Py_None);
518 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000519}
520
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000521static char stat_result__doc__[] =
522"stat_result: Result from stat or lstat.\n\n\
523This object may be accessed either as a tuple of\n\
524 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
525or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
526\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000527Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000528they are available as attributes only.\n\
529\n\
530See os.stat for more information.\n";
531
532static PyStructSequence_Field stat_result_fields[] = {
533 {"st_mode", "protection bits"},
534 {"st_ino", "inode"},
535 {"st_dev", "device"},
536 {"st_nlink", "number of hard links"},
537 {"st_uid", "user ID of owner"},
538 {"st_gid", "group ID of owner"},
539 {"st_size", "total size, in bytes"},
540 {"st_atime", "time of last access"},
541 {"st_mtime", "time of last modification"},
542 {"st_ctime", "time of last change"},
543#ifdef HAVE_ST_BLKSIZE
544 {"st_blksize", "blocksize for filesystem I/O"},
545#endif
546#ifdef HAVE_ST_BLOCKS
547 {"st_blocks", "number of blocks allocated"},
548#endif
549#ifdef HAVE_ST_RDEV
550 {"st_rdev", "device type (if inode device)"},
551#endif
552 {0}
553};
554
555#ifdef HAVE_ST_BLKSIZE
556#define ST_BLKSIZE_IDX 10
557#else
558#define ST_BLKSIZE_IDX 9
559#endif
560
561#ifdef HAVE_ST_BLOCKS
562#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
563#else
564#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
565#endif
566
567#ifdef HAVE_ST_RDEV
568#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
569#else
570#define ST_RDEV_IDX ST_BLOCKS_IDX
571#endif
572
573static PyStructSequence_Desc stat_result_desc = {
574 "stat_result", /* name */
575 stat_result__doc__, /* doc */
576 stat_result_fields,
577 10
578};
579
580static char statvfs_result__doc__[] =
581"statvfs_result: Result from statvfs or fstatvfs.\n\n\
582This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000583 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
584or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000585\n\
586See os.statvfs for more information.\n";
587
588static PyStructSequence_Field statvfs_result_fields[] = {
589 {"f_bsize", },
590 {"f_frsize", },
591 {"f_blocks", },
592 {"f_bfree", },
593 {"f_bavail", },
594 {"f_files", },
595 {"f_ffree", },
596 {"f_favail", },
597 {"f_flag", },
598 {"f_namemax",},
599 {0}
600};
601
602static PyStructSequence_Desc statvfs_result_desc = {
603 "statvfs_result", /* name */
604 statvfs_result__doc__, /* doc */
605 statvfs_result_fields,
606 10
607};
608
609static PyTypeObject StatResultType;
610static PyTypeObject StatVFSResultType;
611
Fred Drake699f3522000-06-29 21:12:41 +0000612/* pack a system stat C structure into the Python stat tuple
613 (used by posix_stat() and posix_fstat()) */
614static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000615_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000616{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000617 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000618 if (v == NULL)
619 return NULL;
620
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000621 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000622#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000623 PyStructSequence_SET_ITEM(v, 1,
624 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000625#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000626 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000627#endif
628#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000629 PyStructSequence_SET_ITEM(v, 2,
630 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000631#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000632 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000633#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000634 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
635 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
636 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000637#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000638 PyStructSequence_SET_ITEM(v, 6,
639 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000640#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000641 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000642#endif
643#if SIZEOF_TIME_T > SIZEOF_LONG
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000644 PyStructSequence_SET_ITEM(v, 7,
645 PyLong_FromLongLong((LONG_LONG)st.st_atime));
646 PyStructSequence_SET_ITEM(v, 8,
647 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
648 PyStructSequence_SET_ITEM(v, 9,
649 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000650#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000651 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
652 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
653 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
654#endif
655
656#ifdef HAVE_ST_BLKSIZE
657 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
658 PyInt_FromLong((long)st.st_blksize));
659#endif
660#ifdef HAVE_ST_BLOCKS
661 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
662 PyInt_FromLong((long)st.st_blocks));
663#endif
664#ifdef HAVE_ST_RDEV
665 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
666 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000667#endif
668
669 if (PyErr_Occurred()) {
670 Py_DECREF(v);
671 return NULL;
672 }
673
674 return v;
675}
676
Barry Warsaw53699e91996-12-10 23:23:01 +0000677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000678posix_do_stat(PyObject *self, PyObject *args, char *format,
679 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000680{
Fred Drake699f3522000-06-29 21:12:41 +0000681 STRUCT_STAT st;
Mark Hammondef8b6542001-05-13 08:04:26 +0000682 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000683 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000684
685#ifdef MS_WIN32
686 int pathlen;
687 char pathcopy[MAX_PATH];
688#endif /* MS_WIN32 */
689
Mark Hammondef8b6542001-05-13 08:04:26 +0000690 if (!PyArg_ParseTuple(args, format,
691 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000692 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000693
694#ifdef MS_WIN32
695 pathlen = strlen(path);
696 /* the library call can blow up if the file name is too long! */
697 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000698 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000699 errno = ENAMETOOLONG;
700 return posix_error();
701 }
702
703 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000704 /* exception for specific or current drive root */
705 if (!((pathlen == 1) ||
706 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000707 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000708 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000709 {
710 strncpy(pathcopy, path, pathlen);
711 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
712 path = pathcopy;
713 }
714 }
715#endif /* MS_WIN32 */
716
Barry Warsaw53699e91996-12-10 23:23:01 +0000717 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000718 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000719 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000720 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000721 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000722
Mark Hammondef8b6542001-05-13 08:04:26 +0000723 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000724 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725}
726
727
728/* POSIX methods */
729
Guido van Rossum94f6f721999-01-06 18:42:14 +0000730static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000731"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000732Test for access to a file.";
733
734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000735posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000736{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000737 char *path;
738 int mode;
739 int res;
740
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000741 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000742 return NULL;
743 Py_BEGIN_ALLOW_THREADS
744 res = access(path, mode);
745 Py_END_ALLOW_THREADS
746 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000747}
748
Guido van Rossumd371ff11999-01-25 16:12:23 +0000749#ifndef F_OK
750#define F_OK 0
751#endif
752#ifndef R_OK
753#define R_OK 4
754#endif
755#ifndef W_OK
756#define W_OK 2
757#endif
758#ifndef X_OK
759#define X_OK 1
760#endif
761
762#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000763static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000764"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000765Return the name of the terminal device connected to 'fd'.";
766
767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000768posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000769{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000770 int id;
771 char *ret;
772
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000773 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000774 return NULL;
775
Guido van Rossum94f6f721999-01-06 18:42:14 +0000776 ret = ttyname(id);
777 if (ret == NULL)
778 return(posix_error());
779 return(PyString_FromString(ret));
780}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000781#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000782
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000783#ifdef HAVE_CTERMID
784static char posix_ctermid__doc__[] =
785"ctermid() -> String\n\
786Return the name of the controlling terminal for this process.";
787
788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000789posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000790{
791 char *ret;
792 char buffer[L_ctermid];
793
794 if (!PyArg_ParseTuple(args, ":ctermid"))
795 return NULL;
796
Greg Wardb48bc172000-03-01 21:51:56 +0000797#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000798 ret = ctermid_r(buffer);
799#else
800 ret = ctermid(buffer);
801#endif
802 if (ret == NULL)
803 return(posix_error());
804 return(PyString_FromString(buffer));
805}
806#endif
807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000808static char posix_chdir__doc__[] =
809"chdir(path) -> None\n\
810Change the current working directory to the specified path.";
811
Barry Warsaw53699e91996-12-10 23:23:01 +0000812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000813posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000814{
Mark Hammondef8b6542001-05-13 08:04:26 +0000815 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000816}
817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000818
819static char posix_chmod__doc__[] =
820"chmod(path, mode) -> None\n\
821Change the access permissions of a file.";
822
Barry Warsaw53699e91996-12-10 23:23:01 +0000823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000824posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000825{
Mark Hammondef8b6542001-05-13 08:04:26 +0000826 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000827 int i;
828 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000829 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
830 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000831 return NULL;
832 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000833 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000834 Py_END_ALLOW_THREADS
835 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000836 return posix_error_with_allocated_filename(path);
837 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000838 Py_INCREF(Py_None);
839 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000840}
841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000842
Martin v. Löwis244edc82001-10-04 22:44:26 +0000843#ifdef HAVE_CHROOT
844static char posix_chroot__doc__[] =
845"chroot(path) -> None\n\
846Change root directory to path.";
847
848static PyObject *
849posix_chroot(PyObject *self, PyObject *args)
850{
851 return posix_1str(args, "et:chroot", chroot);
852}
853#endif
854
Guido van Rossum21142a01999-01-08 21:05:37 +0000855#ifdef HAVE_FSYNC
856static char posix_fsync__doc__[] =
857"fsync(fildes) -> None\n\
858force write of file with filedescriptor to disk.";
859
860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000861posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000862{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000863 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000864}
865#endif /* HAVE_FSYNC */
866
867#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000868
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000869#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000870extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
871#endif
872
Guido van Rossum21142a01999-01-08 21:05:37 +0000873static char posix_fdatasync__doc__[] =
874"fdatasync(fildes) -> None\n\
875force write of file with filedescriptor to disk.\n\
876 does not force update of metadata.";
877
878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000879posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000880{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000881 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000882}
883#endif /* HAVE_FDATASYNC */
884
885
Fredrik Lundh10723342000-07-10 16:38:09 +0000886#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000887static char posix_chown__doc__[] =
888"chown(path, uid, gid) -> None\n\
889Change the owner and group id of path to the numeric uid and gid.";
890
Barry Warsaw53699e91996-12-10 23:23:01 +0000891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000892posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000893{
Mark Hammondef8b6542001-05-13 08:04:26 +0000894 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000895 int uid, gid;
896 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000897 if (!PyArg_ParseTuple(args, "etii:chown",
898 Py_FileSystemDefaultEncoding, &path,
899 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000900 return NULL;
901 Py_BEGIN_ALLOW_THREADS
902 res = chown(path, (uid_t) uid, (gid_t) gid);
903 Py_END_ALLOW_THREADS
904 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000905 return posix_error_with_allocated_filename(path);
906 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000907 Py_INCREF(Py_None);
908 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000909}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000910#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000912
Guido van Rossum36bc6801995-06-14 22:54:23 +0000913#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000914static char posix_getcwd__doc__[] =
915"getcwd() -> path\n\
916Return a string representing the current working directory.";
917
Barry Warsaw53699e91996-12-10 23:23:01 +0000918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000919posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920{
921 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000922 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000923 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000924 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000925 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000926 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000927 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000928 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000929 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000930 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000931}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000932#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000934
Guido van Rossumb6775db1994-08-01 11:34:53 +0000935#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000936static char posix_link__doc__[] =
937"link(src, dst) -> None\n\
938Create a hard link to a file.";
939
Barry Warsaw53699e91996-12-10 23:23:01 +0000940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000941posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000942{
Mark Hammondef8b6542001-05-13 08:04:26 +0000943 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000944}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000945#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000947
948static char posix_listdir__doc__[] =
949"listdir(path) -> list_of_strings\n\
950Return a list containing the names of the entries in the directory.\n\
951\n\
952 path: path of directory to list\n\
953\n\
954The list is in arbitrary order. It does not include the special\n\
955entries '.' and '..' even if they are present in the directory.";
956
Barry Warsaw53699e91996-12-10 23:23:01 +0000957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000958posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000959{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000960 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000961 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000962#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000963
Barry Warsaw53699e91996-12-10 23:23:01 +0000964 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000965 HANDLE hFindFile;
966 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000967 /* MAX_PATH characters could mean a bigger encoded string */
968 char namebuf[MAX_PATH*2+5];
969 char *bufptr = namebuf;
970 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000971 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000972
Mark Hammondef8b6542001-05-13 08:04:26 +0000973 if (!PyArg_ParseTuple(args, "et#:listdir",
974 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000975 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000976 ch = namebuf[len-1];
977 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000978 namebuf[len++] = '/';
979 strcpy(namebuf + len, "*.*");
980
Barry Warsaw53699e91996-12-10 23:23:01 +0000981 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000982 return NULL;
983
984 hFindFile = FindFirstFile(namebuf, &FileData);
985 if (hFindFile == INVALID_HANDLE_VALUE) {
986 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000987 if (errno == ERROR_FILE_NOT_FOUND)
988 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000989 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000990 }
991 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000992 if (FileData.cFileName[0] == '.' &&
993 (FileData.cFileName[1] == '\0' ||
994 FileData.cFileName[1] == '.' &&
995 FileData.cFileName[2] == '\0'))
996 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000997 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000998 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000999 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001000 d = NULL;
1001 break;
1002 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001003 if (PyList_Append(d, v) != 0) {
1004 Py_DECREF(v);
1005 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001006 d = NULL;
1007 break;
1008 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001009 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001010 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1011
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001012 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001013 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001014
1015 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001016
Tim Peters0bb44a42000-09-15 07:44:49 +00001017#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001018
1019#ifndef MAX_PATH
1020#define MAX_PATH 250
1021#endif
1022 char *name, *pt;
1023 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001024 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001025 char namebuf[MAX_PATH+5];
1026 struct _find_t ep;
1027
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001028 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001029 return NULL;
1030 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001031 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001032 return NULL;
1033 }
1034 strcpy(namebuf, name);
1035 for (pt = namebuf; *pt; pt++)
1036 if (*pt == '/')
1037 *pt = '\\';
1038 if (namebuf[len-1] != '\\')
1039 namebuf[len++] = '\\';
1040 strcpy(namebuf + len, "*.*");
1041
Barry Warsaw53699e91996-12-10 23:23:01 +00001042 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001043 return NULL;
1044
1045 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001046 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1047 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001048 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001049 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001050 }
1051 do {
1052 if (ep.name[0] == '.' &&
1053 (ep.name[1] == '\0' ||
1054 ep.name[1] == '.' &&
1055 ep.name[2] == '\0'))
1056 continue;
1057 strcpy(namebuf, ep.name);
1058 for (pt = namebuf; *pt; pt++)
1059 if (isupper(*pt))
1060 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001061 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001062 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001063 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001064 d = NULL;
1065 break;
1066 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001067 if (PyList_Append(d, v) != 0) {
1068 Py_DECREF(v);
1069 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001070 d = NULL;
1071 break;
1072 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001073 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001074 } while (_dos_findnext(&ep) == 0);
1075
1076 return d;
1077
Tim Peters0bb44a42000-09-15 07:44:49 +00001078#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001079
1080#ifndef MAX_PATH
1081#define MAX_PATH CCHMAXPATH
1082#endif
1083 char *name, *pt;
1084 int len;
1085 PyObject *d, *v;
1086 char namebuf[MAX_PATH+5];
1087 HDIR hdir = 1;
1088 ULONG srchcnt = 1;
1089 FILEFINDBUF3 ep;
1090 APIRET rc;
1091
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001092 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001093 return NULL;
1094 if (len >= MAX_PATH) {
1095 PyErr_SetString(PyExc_ValueError, "path too long");
1096 return NULL;
1097 }
1098 strcpy(namebuf, name);
1099 for (pt = namebuf; *pt; pt++)
1100 if (*pt == '/')
1101 *pt = '\\';
1102 if (namebuf[len-1] != '\\')
1103 namebuf[len++] = '\\';
1104 strcpy(namebuf + len, "*.*");
1105
1106 if ((d = PyList_New(0)) == NULL)
1107 return NULL;
1108
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001109 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1110 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001111 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001112 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1113 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1114 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001115
1116 if (rc != NO_ERROR) {
1117 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001118 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001119 }
1120
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001121 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001122 do {
1123 if (ep.achName[0] == '.'
1124 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001125 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001126
1127 strcpy(namebuf, ep.achName);
1128
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001129 /* Leave Case of Name Alone -- In Native Form */
1130 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001131
1132 v = PyString_FromString(namebuf);
1133 if (v == NULL) {
1134 Py_DECREF(d);
1135 d = NULL;
1136 break;
1137 }
1138 if (PyList_Append(d, v) != 0) {
1139 Py_DECREF(v);
1140 Py_DECREF(d);
1141 d = NULL;
1142 break;
1143 }
1144 Py_DECREF(v);
1145 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1146 }
1147
1148 return d;
1149#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001150
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001151 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001152 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001154 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001155 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001156 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001157 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001158 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001159 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001160 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001161 closedir(dirp);
1162 return NULL;
1163 }
1164 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001165 if (ep->d_name[0] == '.' &&
1166 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001167 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001168 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001169 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001170 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001171 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001172 d = NULL;
1173 break;
1174 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001175 if (PyList_Append(d, v) != 0) {
1176 Py_DECREF(v);
1177 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178 d = NULL;
1179 break;
1180 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001181 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182 }
1183 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001184
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001186
Tim Peters0bb44a42000-09-15 07:44:49 +00001187#endif /* which OS */
1188} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189
Mark Hammondef8b6542001-05-13 08:04:26 +00001190#ifdef MS_WIN32
1191/* A helper function for abspath on win32 */
1192static PyObject *
1193posix__getfullpathname(PyObject *self, PyObject *args)
1194{
1195 /* assume encoded strings wont more than double no of chars */
1196 char inbuf[MAX_PATH*2];
1197 char *inbufp = inbuf;
1198 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1199 char outbuf[MAX_PATH*2];
1200 char *temp;
1201 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1202 Py_FileSystemDefaultEncoding, &inbufp,
1203 &insize))
1204 return NULL;
1205 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1206 outbuf, &temp))
1207 return win32_error("GetFullPathName", inbuf);
1208 return PyString_FromString(outbuf);
1209} /* end of posix__getfullpathname */
1210#endif /* MS_WIN32 */
1211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001212static char posix_mkdir__doc__[] =
1213"mkdir(path [, mode=0777]) -> None\n\
1214Create a directory.";
1215
Barry Warsaw53699e91996-12-10 23:23:01 +00001216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001217posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001219 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001220 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001221 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001222 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1223 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001224 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001225 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001226#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001227 res = mkdir(path);
1228#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001229 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001230#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001231 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001232 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001233 return posix_error_with_allocated_filename(path);
1234 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001235 Py_INCREF(Py_None);
1236 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001237}
1238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001239
Guido van Rossumb6775db1994-08-01 11:34:53 +00001240#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001241#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1242#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1243#include <sys/resource.h>
1244#endif
1245#endif
1246
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001247static char posix_nice__doc__[] =
1248"nice(inc) -> new_priority\n\
1249Decrease the priority of process and return new priority.";
1250
Barry Warsaw53699e91996-12-10 23:23:01 +00001251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001252posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001253{
1254 int increment, value;
1255
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001256 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001257 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001258
1259 /* There are two flavours of 'nice': one that returns the new
1260 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001261 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1262 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001263
1264 If we are of the nice family that returns the new priority, we
1265 need to clear errno before the call, and check if errno is filled
1266 before calling posix_error() on a returnvalue of -1, because the
1267 -1 may be the actual new priority! */
1268
1269 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001270 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001271#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001272 if (value == 0)
1273 value = getpriority(PRIO_PROCESS, 0);
1274#endif
1275 if (value == -1 && errno != 0)
1276 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001277 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001278 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001279}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001280#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001281
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001282
1283static char posix_rename__doc__[] =
1284"rename(old, new) -> None\n\
1285Rename a file or directory.";
1286
Barry Warsaw53699e91996-12-10 23:23:01 +00001287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001288posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001289{
Mark Hammondef8b6542001-05-13 08:04:26 +00001290 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001291}
1292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001293
1294static char posix_rmdir__doc__[] =
1295"rmdir(path) -> None\n\
1296Remove a directory.";
1297
Barry Warsaw53699e91996-12-10 23:23:01 +00001298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001299posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001300{
Mark Hammondef8b6542001-05-13 08:04:26 +00001301 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001302}
1303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001304
1305static char posix_stat__doc__[] =
1306"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1307Perform a stat system call on the given path.";
1308
Barry Warsaw53699e91996-12-10 23:23:01 +00001309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001310posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001311{
Mark Hammondef8b6542001-05-13 08:04:26 +00001312 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001313}
1314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001315
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001316#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001317static char posix_system__doc__[] =
1318"system(command) -> exit_status\n\
1319Execute the command (a string) in a subshell.";
1320
Barry Warsaw53699e91996-12-10 23:23:01 +00001321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001322posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001323{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001324 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001325 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001326 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001327 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001328 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001329 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001330 Py_END_ALLOW_THREADS
1331 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001332}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001333#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
1336static char posix_umask__doc__[] =
1337"umask(new_mask) -> old_mask\n\
1338Set the current numeric umask and return the previous umask.";
1339
Barry Warsaw53699e91996-12-10 23:23:01 +00001340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001341posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342{
1343 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001344 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001345 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001346 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001347 if (i < 0)
1348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001349 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350}
1351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001352
1353static char posix_unlink__doc__[] =
1354"unlink(path) -> None\n\
1355Remove a file (same as remove(path)).";
1356
1357static char posix_remove__doc__[] =
1358"remove(path) -> None\n\
1359Remove a file (same as unlink(path)).";
1360
Barry Warsaw53699e91996-12-10 23:23:01 +00001361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001362posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001363{
Mark Hammondef8b6542001-05-13 08:04:26 +00001364 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365}
1366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001367
Guido van Rossumb6775db1994-08-01 11:34:53 +00001368#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001369static char posix_uname__doc__[] =
1370"uname() -> (sysname, nodename, release, version, machine)\n\
1371Return a tuple identifying the current operating system.";
1372
Barry Warsaw53699e91996-12-10 23:23:01 +00001373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001374posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001375{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001376 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001377 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001378 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001379 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001380 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001381 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001382 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001383 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001384 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001385 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001386 u.sysname,
1387 u.nodename,
1388 u.release,
1389 u.version,
1390 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001391}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001392#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001394
1395static char posix_utime__doc__[] =
1396"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001397utime(path, None) -> None\n\
1398Set the access and modified time of the file to the given values. If the\n\
1399second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001400
Barry Warsaw53699e91996-12-10 23:23:01 +00001401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001402posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001403{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001404 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001405 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001406 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001407 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001408
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001409/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001410#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001411 struct utimbuf buf;
1412#define ATIME buf.actime
1413#define MTIME buf.modtime
1414#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001415#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001416 time_t buf[2];
1417#define ATIME buf[0]
1418#define MTIME buf[1]
1419#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001420#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001421
Barry Warsaw3cef8562000-05-01 16:17:24 +00001422 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001424 if (arg == Py_None) {
1425 /* optional time values not given */
1426 Py_BEGIN_ALLOW_THREADS
1427 res = utime(path, NULL);
1428 Py_END_ALLOW_THREADS
1429 }
1430 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1431 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001432 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001433 return NULL;
1434 }
1435 else {
1436 ATIME = atime;
1437 MTIME = mtime;
1438 Py_BEGIN_ALLOW_THREADS
1439 res = utime(path, UTIME_ARG);
1440 Py_END_ALLOW_THREADS
1441 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001442 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001443 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001444 Py_INCREF(Py_None);
1445 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001446#undef UTIME_ARG
1447#undef ATIME
1448#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001449}
1450
Guido van Rossum85e3b011991-06-03 12:42:10 +00001451
Guido van Rossum3b066191991-06-04 19:40:25 +00001452/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001453
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001454static char posix__exit__doc__[] =
1455"_exit(status)\n\
1456Exit to the system with specified status, without normal exit processing.";
1457
Barry Warsaw53699e91996-12-10 23:23:01 +00001458static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001459posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001460{
1461 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001462 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001463 return NULL;
1464 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001465 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001466}
1467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001468
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001469#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001470static char posix_execv__doc__[] =
1471"execv(path, args)\n\
1472Execute an executable path with arguments, replacing current process.\n\
1473\n\
1474 path: path of executable file\n\
1475 args: tuple or list of strings";
1476
Barry Warsaw53699e91996-12-10 23:23:01 +00001477static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001478posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001479{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001480 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001481 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001482 char **argvlist;
1483 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001484 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001485
Guido van Rossum89b33251993-10-22 14:26:06 +00001486 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001487 argv is a list or tuple of strings. */
1488
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001489 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001490 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001491 if (PyList_Check(argv)) {
1492 argc = PyList_Size(argv);
1493 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001494 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001495 else if (PyTuple_Check(argv)) {
1496 argc = PyTuple_Size(argv);
1497 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001498 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001499 else {
Fred Drake661ea262000-10-24 19:57:45 +00001500 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001501 return NULL;
1502 }
1503
1504 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001505 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001506 return NULL;
1507 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001508
Barry Warsaw53699e91996-12-10 23:23:01 +00001509 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001510 if (argvlist == NULL)
1511 return NULL;
1512 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001513 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1514 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001515 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001516 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001517 return NULL;
1518
Guido van Rossum85e3b011991-06-03 12:42:10 +00001519 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001520 }
1521 argvlist[argc] = NULL;
1522
Guido van Rossumb6775db1994-08-01 11:34:53 +00001523#ifdef BAD_EXEC_PROTOTYPES
1524 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001525#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001526 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001527#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001528
Guido van Rossum85e3b011991-06-03 12:42:10 +00001529 /* If we get here it's definitely an error */
1530
Barry Warsaw53699e91996-12-10 23:23:01 +00001531 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001532 return posix_error();
1533}
1534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001535
1536static char posix_execve__doc__[] =
1537"execve(path, args, env)\n\
1538Execute a path with arguments and environment, replacing current process.\n\
1539\n\
1540 path: path of executable file\n\
1541 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001542 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001543
Barry Warsaw53699e91996-12-10 23:23:01 +00001544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001545posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001546{
1547 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001548 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001549 char **argvlist;
1550 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001551 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001552 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001553 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001554
1555 /* execve has three arguments: (path, argv, env), where
1556 argv is a list or tuple of strings and env is a dictionary
1557 like posix.environ. */
1558
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001559 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001560 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001561 if (PyList_Check(argv)) {
1562 argc = PyList_Size(argv);
1563 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001564 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001565 else if (PyTuple_Check(argv)) {
1566 argc = PyTuple_Size(argv);
1567 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001568 }
1569 else {
Fred Drake661ea262000-10-24 19:57:45 +00001570 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001571 return NULL;
1572 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001573 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001574 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001575 return NULL;
1576 }
1577
Guido van Rossum50422b42000-04-26 20:34:28 +00001578 if (argc == 0) {
1579 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001580 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001581 return NULL;
1582 }
1583
Barry Warsaw53699e91996-12-10 23:23:01 +00001584 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001585 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001586 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001587 return NULL;
1588 }
1589 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001590 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001591 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001592 &argvlist[i]))
1593 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001594 goto fail_1;
1595 }
1596 }
1597 argvlist[argc] = NULL;
1598
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001599 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001600 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001602 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001603 goto fail_1;
1604 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001605 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001606 keys = PyMapping_Keys(env);
1607 vals = PyMapping_Values(env);
1608 if (!keys || !vals)
1609 goto fail_2;
1610
1611 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001612 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001613
1614 key = PyList_GetItem(keys, pos);
1615 val = PyList_GetItem(vals, pos);
1616 if (!key || !val)
1617 goto fail_2;
1618
Fred Drake661ea262000-10-24 19:57:45 +00001619 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1620 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001621 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001622 goto fail_2;
1623 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001624
1625#if defined(PYOS_OS2)
1626 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1627 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1628#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001629 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001630 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001631 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001632 goto fail_2;
1633 }
1634 sprintf(p, "%s=%s", k, v);
1635 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001636#if defined(PYOS_OS2)
1637 }
1638#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001639 }
1640 envlist[envc] = 0;
1641
Guido van Rossumb6775db1994-08-01 11:34:53 +00001642
1643#ifdef BAD_EXEC_PROTOTYPES
1644 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001645#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001646 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001647#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001648
1649 /* If we get here it's definitely an error */
1650
1651 (void) posix_error();
1652
1653 fail_2:
1654 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001655 PyMem_DEL(envlist[envc]);
1656 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001657 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001658 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001659 Py_XDECREF(vals);
1660 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001661 return NULL;
1662}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001663#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001664
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001665
Guido van Rossuma1065681999-01-25 23:20:23 +00001666#ifdef HAVE_SPAWNV
1667static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001668"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001669Execute an executable path with arguments, replacing current process.\n\
1670\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001671 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001672 path: path of executable file\n\
1673 args: tuple or list of strings";
1674
1675static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001676posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001677{
1678 char *path;
1679 PyObject *argv;
1680 char **argvlist;
1681 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001682 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001683 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001684
1685 /* spawnv has three arguments: (mode, path, argv), where
1686 argv is a list or tuple of strings. */
1687
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001688 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001689 return NULL;
1690 if (PyList_Check(argv)) {
1691 argc = PyList_Size(argv);
1692 getitem = PyList_GetItem;
1693 }
1694 else if (PyTuple_Check(argv)) {
1695 argc = PyTuple_Size(argv);
1696 getitem = PyTuple_GetItem;
1697 }
1698 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001699 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001700 return NULL;
1701 }
1702
1703 argvlist = PyMem_NEW(char *, argc+1);
1704 if (argvlist == NULL)
1705 return NULL;
1706 for (i = 0; i < argc; i++) {
1707 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1708 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001709 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001710 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001711 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001712 }
1713 }
1714 argvlist[argc] = NULL;
1715
Guido van Rossum246bc171999-02-01 23:54:31 +00001716 if (mode == _OLD_P_OVERLAY)
1717 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001718 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001719
1720 PyMem_DEL(argvlist);
1721
Fred Drake699f3522000-06-29 21:12:41 +00001722 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001723 return posix_error();
1724 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001725#if SIZEOF_LONG == SIZEOF_VOID_P
1726 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001727#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001728 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001729#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001730}
1731
1732
1733static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001734"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001735Execute a path with arguments and environment, replacing current process.\n\
1736\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001737 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001738 path: path of executable file\n\
1739 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001740 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001741
1742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001743posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001744{
1745 char *path;
1746 PyObject *argv, *env;
1747 char **argvlist;
1748 char **envlist;
1749 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1750 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001751 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001752 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001753
1754 /* spawnve has four arguments: (mode, path, argv, env), where
1755 argv is a list or tuple of strings and env is a dictionary
1756 like posix.environ. */
1757
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001758 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001759 return NULL;
1760 if (PyList_Check(argv)) {
1761 argc = PyList_Size(argv);
1762 getitem = PyList_GetItem;
1763 }
1764 else if (PyTuple_Check(argv)) {
1765 argc = PyTuple_Size(argv);
1766 getitem = PyTuple_GetItem;
1767 }
1768 else {
Fred Drake661ea262000-10-24 19:57:45 +00001769 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001770 return NULL;
1771 }
1772 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001773 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001774 return NULL;
1775 }
1776
1777 argvlist = PyMem_NEW(char *, argc+1);
1778 if (argvlist == NULL) {
1779 PyErr_NoMemory();
1780 return NULL;
1781 }
1782 for (i = 0; i < argc; i++) {
1783 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001784 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001785 &argvlist[i]))
1786 {
1787 goto fail_1;
1788 }
1789 }
1790 argvlist[argc] = NULL;
1791
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001792 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001793 envlist = PyMem_NEW(char *, i + 1);
1794 if (envlist == NULL) {
1795 PyErr_NoMemory();
1796 goto fail_1;
1797 }
1798 envc = 0;
1799 keys = PyMapping_Keys(env);
1800 vals = PyMapping_Values(env);
1801 if (!keys || !vals)
1802 goto fail_2;
1803
1804 for (pos = 0; pos < i; pos++) {
1805 char *p, *k, *v;
1806
1807 key = PyList_GetItem(keys, pos);
1808 val = PyList_GetItem(vals, pos);
1809 if (!key || !val)
1810 goto fail_2;
1811
Fred Drake661ea262000-10-24 19:57:45 +00001812 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1813 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001814 {
1815 goto fail_2;
1816 }
1817 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1818 if (p == NULL) {
1819 PyErr_NoMemory();
1820 goto fail_2;
1821 }
1822 sprintf(p, "%s=%s", k, v);
1823 envlist[envc++] = p;
1824 }
1825 envlist[envc] = 0;
1826
Guido van Rossum246bc171999-02-01 23:54:31 +00001827 if (mode == _OLD_P_OVERLAY)
1828 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001829 spawnval = _spawnve(mode, path, argvlist, envlist);
1830 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001831 (void) posix_error();
1832 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001833#if SIZEOF_LONG == SIZEOF_VOID_P
1834 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001835#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001836 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001837#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001838
1839 fail_2:
1840 while (--envc >= 0)
1841 PyMem_DEL(envlist[envc]);
1842 PyMem_DEL(envlist);
1843 fail_1:
1844 PyMem_DEL(argvlist);
1845 Py_XDECREF(vals);
1846 Py_XDECREF(keys);
1847 return res;
1848}
1849#endif /* HAVE_SPAWNV */
1850
1851
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001852#ifdef HAVE_FORK1
1853static char posix_fork1__doc__[] =
1854"fork1() -> pid\n\
1855Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1856\n\
1857Return 0 to child process and PID of child to parent process.";
1858
1859static PyObject *
1860posix_fork1(self, args)
1861 PyObject *self;
1862 PyObject *args;
1863{
1864 int pid;
1865 if (!PyArg_ParseTuple(args, ":fork1"))
1866 return NULL;
1867 pid = fork1();
1868 if (pid == -1)
1869 return posix_error();
1870 PyOS_AfterFork();
1871 return PyInt_FromLong((long)pid);
1872}
1873#endif
1874
1875
Guido van Rossumad0ee831995-03-01 10:34:45 +00001876#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001877static char posix_fork__doc__[] =
1878"fork() -> pid\n\
1879Fork a child process.\n\
1880\n\
1881Return 0 to child process and PID of child to parent process.";
1882
Barry Warsaw53699e91996-12-10 23:23:01 +00001883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001884posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001885{
1886 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001887 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001888 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001889 pid = fork();
1890 if (pid == -1)
1891 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001892 if (pid == 0)
1893 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001894 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001895}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001896#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001897
Fred Drake8cef4cf2000-06-28 16:40:38 +00001898#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1899#ifdef HAVE_PTY_H
1900#include <pty.h>
1901#else
1902#ifdef HAVE_LIBUTIL_H
1903#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001904#endif /* HAVE_LIBUTIL_H */
1905#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001906#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001907
Thomas Wouters70c21a12000-07-14 14:28:33 +00001908#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001909static char posix_openpty__doc__[] =
1910"openpty() -> (master_fd, slave_fd)\n\
1911Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1912
1913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001914posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001915{
1916 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001917#ifndef HAVE_OPENPTY
1918 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001919#endif
1920
Fred Drake8cef4cf2000-06-28 16:40:38 +00001921 if (!PyArg_ParseTuple(args, ":openpty"))
1922 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001923
1924#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001925 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1926 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001927#else
1928 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1929 if (slave_name == NULL)
1930 return posix_error();
1931
1932 slave_fd = open(slave_name, O_RDWR);
1933 if (slave_fd < 0)
1934 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001935#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001936
Fred Drake8cef4cf2000-06-28 16:40:38 +00001937 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001938
Fred Drake8cef4cf2000-06-28 16:40:38 +00001939}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001940#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001941
1942#ifdef HAVE_FORKPTY
1943static char posix_forkpty__doc__[] =
1944"forkpty() -> (pid, master_fd)\n\
1945Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1946Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1947To both, return fd of newly opened pseudo-terminal.\n";
1948
1949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001950posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001951{
1952 int master_fd, pid;
1953
1954 if (!PyArg_ParseTuple(args, ":forkpty"))
1955 return NULL;
1956 pid = forkpty(&master_fd, NULL, NULL, NULL);
1957 if (pid == -1)
1958 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001959 if (pid == 0)
1960 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001961 return Py_BuildValue("(ii)", pid, master_fd);
1962}
1963#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001964
Guido van Rossumad0ee831995-03-01 10:34:45 +00001965#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001966static char posix_getegid__doc__[] =
1967"getegid() -> egid\n\
1968Return the current process's effective group id.";
1969
Barry Warsaw53699e91996-12-10 23:23:01 +00001970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001971posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001972{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001973 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001974 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001975 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001976}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001977#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001979
Guido van Rossumad0ee831995-03-01 10:34:45 +00001980#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001981static char posix_geteuid__doc__[] =
1982"geteuid() -> euid\n\
1983Return the current process's effective user id.";
1984
Barry Warsaw53699e91996-12-10 23:23:01 +00001985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001986posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001987{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001988 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001989 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001990 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001991}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001992#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001994
Guido van Rossumad0ee831995-03-01 10:34:45 +00001995#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001996static char posix_getgid__doc__[] =
1997"getgid() -> gid\n\
1998Return the current process's group id.";
1999
Barry Warsaw53699e91996-12-10 23:23:01 +00002000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002001posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002002{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002003 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002004 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002005 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002006}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002007#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002009
2010static char posix_getpid__doc__[] =
2011"getpid() -> pid\n\
2012Return the current process id";
2013
Barry Warsaw53699e91996-12-10 23:23:01 +00002014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002015posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002016{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002017 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002018 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002019 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002020}
2021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002022
Fred Drakec9680921999-12-13 16:37:25 +00002023#ifdef HAVE_GETGROUPS
2024static char posix_getgroups__doc__[] = "\
2025getgroups() -> list of group IDs\n\
2026Return list of supplemental group IDs for the process.";
2027
2028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002029posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002030{
2031 PyObject *result = NULL;
2032
2033 if (PyArg_ParseTuple(args, ":getgroups")) {
2034#ifdef NGROUPS_MAX
2035#define MAX_GROUPS NGROUPS_MAX
2036#else
2037 /* defined to be 16 on Solaris7, so this should be a small number */
2038#define MAX_GROUPS 64
2039#endif
2040 gid_t grouplist[MAX_GROUPS];
2041 int n;
2042
2043 n = getgroups(MAX_GROUPS, grouplist);
2044 if (n < 0)
2045 posix_error();
2046 else {
2047 result = PyList_New(n);
2048 if (result != NULL) {
2049 PyObject *o;
2050 int i;
2051 for (i = 0; i < n; ++i) {
2052 o = PyInt_FromLong((long)grouplist[i]);
2053 if (o == NULL) {
2054 Py_DECREF(result);
2055 result = NULL;
2056 break;
2057 }
2058 PyList_SET_ITEM(result, i, o);
2059 }
2060 }
2061 }
2062 }
2063 return result;
2064}
2065#endif
2066
Guido van Rossumb6775db1994-08-01 11:34:53 +00002067#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068static char posix_getpgrp__doc__[] =
2069"getpgrp() -> pgrp\n\
2070Return the current process group id.";
2071
Barry Warsaw53699e91996-12-10 23:23:01 +00002072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002073posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002074{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002075 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002076 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002077#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002078 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002079#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002080 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002081#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002082}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002083#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002085
Guido van Rossumb6775db1994-08-01 11:34:53 +00002086#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087static char posix_setpgrp__doc__[] =
2088"setpgrp() -> None\n\
2089Make this process a session leader.";
2090
Barry Warsaw53699e91996-12-10 23:23:01 +00002091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002092posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002093{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002094 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002095 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002096#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002097 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002098#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002099 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002100#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002101 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002102 Py_INCREF(Py_None);
2103 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002104}
2105
Guido van Rossumb6775db1994-08-01 11:34:53 +00002106#endif /* HAVE_SETPGRP */
2107
Guido van Rossumad0ee831995-03-01 10:34:45 +00002108#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002109static char posix_getppid__doc__[] =
2110"getppid() -> ppid\n\
2111Return the parent's process id.";
2112
Barry Warsaw53699e91996-12-10 23:23:01 +00002113static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002114posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002115{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002116 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002117 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002118 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002119}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002120#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122
Fred Drake12c6e2d1999-12-14 21:25:03 +00002123#ifdef HAVE_GETLOGIN
2124static char posix_getlogin__doc__[] = "\
2125getlogin() -> string\n\
2126Return the actual login name.";
2127
2128static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002129posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002130{
2131 PyObject *result = NULL;
2132
2133 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002134 char *name;
2135 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002136
Fred Drakea30680b2000-12-06 21:24:28 +00002137 errno = 0;
2138 name = getlogin();
2139 if (name == NULL) {
2140 if (errno)
2141 posix_error();
2142 else
2143 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002144 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002145 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002146 else
2147 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002148 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002149 }
2150 return result;
2151}
2152#endif
2153
Guido van Rossumad0ee831995-03-01 10:34:45 +00002154#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002155static char posix_getuid__doc__[] =
2156"getuid() -> uid\n\
2157Return the current process's user id.";
2158
Barry Warsaw53699e91996-12-10 23:23:01 +00002159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002160posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002161{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002162 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002163 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002164 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002165}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002166#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002168
Guido van Rossumad0ee831995-03-01 10:34:45 +00002169#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002170static char posix_kill__doc__[] =
2171"kill(pid, sig) -> None\n\
2172Kill a process with a signal.";
2173
Barry Warsaw53699e91996-12-10 23:23:01 +00002174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002175posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002176{
2177 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002178 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002179 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002180#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002181 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2182 APIRET rc;
2183 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002184 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002185
2186 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2187 APIRET rc;
2188 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002189 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002190
2191 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002192 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002193#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002194 if (kill(pid, sig) == -1)
2195 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002196#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002197 Py_INCREF(Py_None);
2198 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002199}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002200#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002201
Guido van Rossumc0125471996-06-28 18:55:32 +00002202#ifdef HAVE_PLOCK
2203
2204#ifdef HAVE_SYS_LOCK_H
2205#include <sys/lock.h>
2206#endif
2207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002208static char posix_plock__doc__[] =
2209"plock(op) -> None\n\
2210Lock program segments into memory.";
2211
Barry Warsaw53699e91996-12-10 23:23:01 +00002212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002213posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002214{
2215 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002216 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002217 return NULL;
2218 if (plock(op) == -1)
2219 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002220 Py_INCREF(Py_None);
2221 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002222}
2223#endif
2224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002225
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002226#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002227static char posix_popen__doc__[] =
2228"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2229Open a pipe to/from a command returning a file object.";
2230
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002231#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002232static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002233async_system(const char *command)
2234{
2235 char *p, errormsg[256], args[1024];
2236 RESULTCODES rcodes;
2237 APIRET rc;
2238 char *shell = getenv("COMSPEC");
2239 if (!shell)
2240 shell = "cmd";
2241
2242 strcpy(args, shell);
2243 p = &args[ strlen(args)+1 ];
2244 strcpy(p, "/c ");
2245 strcat(p, command);
2246 p += strlen(p) + 1;
2247 *p = '\0';
2248
2249 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002250 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002251 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002252 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002253 &rcodes, shell);
2254 return rc;
2255}
2256
Guido van Rossumd48f2521997-12-05 22:19:34 +00002257static FILE *
2258popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002259{
2260 HFILE rhan, whan;
2261 FILE *retfd = NULL;
2262 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2263
Guido van Rossumd48f2521997-12-05 22:19:34 +00002264 if (rc != NO_ERROR) {
2265 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002266 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002267 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002268
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002269 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2270 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002271
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002272 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2273 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002274
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002275 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2276 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002277
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002278 rc = async_system(command);
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
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002284 if (rc == NO_ERROR)
2285 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2286
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002287 close(oldfd); /* And Close Saved STDOUT Handle */
2288 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002289
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002290 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2291 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002292
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002293 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2294 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002295
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002296 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2297 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002298
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002299 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002300 }
2301
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002302 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2303 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002304
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002305 if (rc == NO_ERROR)
2306 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2307
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002308 close(oldfd); /* And Close Saved STDIN Handle */
2309 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002310
Guido van Rossumd48f2521997-12-05 22:19:34 +00002311 } else {
2312 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002313 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002314 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002315}
2316
2317static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002318posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002319{
2320 char *name;
2321 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002322 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323 FILE *fp;
2324 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002325 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002326 return NULL;
2327 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002328 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002329 Py_END_ALLOW_THREADS
2330 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002331 return os2_error(err);
2332
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002333 f = PyFile_FromFile(fp, name, mode, fclose);
2334 if (f != NULL)
2335 PyFile_SetBufSize(f, bufsize);
2336 return f;
2337}
2338
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002339#elif defined(MS_WIN32)
2340
2341/*
2342 * Portable 'popen' replacement for Win32.
2343 *
2344 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2345 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002346 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002347 */
2348
2349#include <malloc.h>
2350#include <io.h>
2351#include <fcntl.h>
2352
2353/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2354#define POPEN_1 1
2355#define POPEN_2 2
2356#define POPEN_3 3
2357#define POPEN_4 4
2358
2359static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002360static int _PyPclose(FILE *file);
2361
2362/*
2363 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002364 * for use when retrieving the process exit code. See _PyPclose() below
2365 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002366 */
2367static PyObject *_PyPopenProcs = NULL;
2368
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002369
2370/* popen that works from a GUI.
2371 *
2372 * The result of this function is a pipe (file) connected to the
2373 * processes stdin or stdout, depending on the requested mode.
2374 */
2375
2376static PyObject *
2377posix_popen(PyObject *self, PyObject *args)
2378{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002379 PyObject *f, *s;
2380 int tm = 0;
2381
2382 char *cmdstring;
2383 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002384 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002385 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002386 return NULL;
2387
2388 s = PyTuple_New(0);
2389
2390 if (*mode == 'r')
2391 tm = _O_RDONLY;
2392 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002393 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002394 return NULL;
2395 } else
2396 tm = _O_WRONLY;
2397
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002398 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002399 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002400 return NULL;
2401 }
2402
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002403 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002404 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002405 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002406 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002407 else
2408 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2409
2410 return f;
2411}
2412
2413/* Variation on win32pipe.popen
2414 *
2415 * The result of this function is a pipe (file) connected to the
2416 * process's stdin, and a pipe connected to the process's stdout.
2417 */
2418
2419static PyObject *
2420win32_popen2(PyObject *self, PyObject *args)
2421{
2422 PyObject *f;
2423 int tm=0;
2424
2425 char *cmdstring;
2426 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002427 int bufsize = -1;
2428 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002429 return NULL;
2430
2431 if (*mode == 't')
2432 tm = _O_TEXT;
2433 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002434 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002435 return NULL;
2436 } else
2437 tm = _O_BINARY;
2438
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002439 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002440 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002441 return NULL;
2442 }
2443
2444 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002445
2446 return f;
2447}
2448
2449/*
2450 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002451 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002452 * The result of this function is 3 pipes - the process's stdin,
2453 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002454 */
2455
2456static PyObject *
2457win32_popen3(PyObject *self, PyObject *args)
2458{
2459 PyObject *f;
2460 int tm = 0;
2461
2462 char *cmdstring;
2463 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002464 int bufsize = -1;
2465 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002466 return NULL;
2467
2468 if (*mode == 't')
2469 tm = _O_TEXT;
2470 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002471 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002472 return NULL;
2473 } else
2474 tm = _O_BINARY;
2475
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002476 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002477 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002478 return NULL;
2479 }
2480
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002481 f = _PyPopen(cmdstring, tm, POPEN_3);
2482
2483 return f;
2484}
2485
2486/*
2487 * Variation on win32pipe.popen
2488 *
2489 * The result of this function is 2 pipes - the processes stdin,
2490 * and stdout+stderr combined as a single pipe.
2491 */
2492
2493static PyObject *
2494win32_popen4(PyObject *self, PyObject *args)
2495{
2496 PyObject *f;
2497 int tm = 0;
2498
2499 char *cmdstring;
2500 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002501 int bufsize = -1;
2502 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002503 return NULL;
2504
2505 if (*mode == 't')
2506 tm = _O_TEXT;
2507 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002508 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002509 return NULL;
2510 } else
2511 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002512
2513 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002514 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002515 return NULL;
2516 }
2517
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002518 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002519
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002520 return f;
2521}
2522
Mark Hammond08501372001-01-31 07:30:29 +00002523static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002524_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002525 HANDLE hStdin,
2526 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002527 HANDLE hStderr,
2528 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002529{
2530 PROCESS_INFORMATION piProcInfo;
2531 STARTUPINFO siStartInfo;
2532 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002533 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002534 int i;
2535 int x;
2536
2537 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002538 char *comshell;
2539
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002540 s1 = (char *)_alloca(i);
2541 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2542 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002543
2544 /* Explicitly check if we are using COMMAND.COM. If we are
2545 * then use the w9xpopen hack.
2546 */
2547 comshell = s1 + x;
2548 while (comshell >= s1 && *comshell != '\\')
2549 --comshell;
2550 ++comshell;
2551
2552 if (GetVersion() < 0x80000000 &&
2553 _stricmp(comshell, "command.com") != 0) {
2554 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002555 x = i + strlen(s3) + strlen(cmdstring) + 1;
2556 s2 = (char *)_alloca(x);
2557 ZeroMemory(s2, x);
2558 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2559 }
2560 else {
2561 /*
Tim Peters402d5982001-08-27 06:37:48 +00002562 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2563 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002564 */
Mark Hammond08501372001-01-31 07:30:29 +00002565 char modulepath[_MAX_PATH];
2566 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002567 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2568 for (i = x = 0; modulepath[i]; i++)
2569 if (modulepath[i] == '\\')
2570 x = i+1;
2571 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002572 /* Create the full-name to w9xpopen, so we can test it exists */
2573 strncat(modulepath,
2574 szConsoleSpawn,
2575 (sizeof(modulepath)/sizeof(modulepath[0]))
2576 -strlen(modulepath));
2577 if (stat(modulepath, &statinfo) != 0) {
2578 /* Eeek - file-not-found - possibly an embedding
2579 situation - see if we can locate it in sys.prefix
2580 */
2581 strncpy(modulepath,
2582 Py_GetExecPrefix(),
2583 sizeof(modulepath)/sizeof(modulepath[0]));
2584 if (modulepath[strlen(modulepath)-1] != '\\')
2585 strcat(modulepath, "\\");
2586 strncat(modulepath,
2587 szConsoleSpawn,
2588 (sizeof(modulepath)/sizeof(modulepath[0]))
2589 -strlen(modulepath));
2590 /* No where else to look - raise an easily identifiable
2591 error, rather than leaving Windows to report
2592 "file not found" - as the user is probably blissfully
2593 unaware this shim EXE is used, and it will confuse them.
2594 (well, it confused me for a while ;-)
2595 */
2596 if (stat(modulepath, &statinfo) != 0) {
2597 PyErr_Format(PyExc_RuntimeError,
2598 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002599 "for popen to work with your shell "
2600 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002601 szConsoleSpawn);
2602 return FALSE;
2603 }
2604 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002605 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2606 strlen(modulepath) +
2607 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002608
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002609 s2 = (char *)_alloca(x);
2610 ZeroMemory(s2, x);
2611 sprintf(
2612 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002613 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002614 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002615 s1,
2616 s3,
2617 cmdstring);
2618 }
2619 }
2620
2621 /* Could be an else here to try cmd.exe / command.com in the path
2622 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002623 else {
Tim Peters402d5982001-08-27 06:37:48 +00002624 PyErr_SetString(PyExc_RuntimeError,
2625 "Cannot locate a COMSPEC environment variable to "
2626 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002627 return FALSE;
2628 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002629
2630 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2631 siStartInfo.cb = sizeof(STARTUPINFO);
2632 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2633 siStartInfo.hStdInput = hStdin;
2634 siStartInfo.hStdOutput = hStdout;
2635 siStartInfo.hStdError = hStderr;
2636 siStartInfo.wShowWindow = SW_HIDE;
2637
2638 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002639 s2,
2640 NULL,
2641 NULL,
2642 TRUE,
2643 CREATE_NEW_CONSOLE,
2644 NULL,
2645 NULL,
2646 &siStartInfo,
2647 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002648 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002649 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002650
Mark Hammondb37a3732000-08-14 04:47:33 +00002651 /* Return process handle */
2652 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002653 return TRUE;
2654 }
Tim Peters402d5982001-08-27 06:37:48 +00002655 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002656 return FALSE;
2657}
2658
2659/* The following code is based off of KB: Q190351 */
2660
2661static PyObject *
2662_PyPopen(char *cmdstring, int mode, int n)
2663{
2664 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2665 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002666 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002667
2668 SECURITY_ATTRIBUTES saAttr;
2669 BOOL fSuccess;
2670 int fd1, fd2, fd3;
2671 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002672 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002673 PyObject *f;
2674
2675 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2676 saAttr.bInheritHandle = TRUE;
2677 saAttr.lpSecurityDescriptor = NULL;
2678
2679 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2680 return win32_error("CreatePipe", NULL);
2681
2682 /* Create new output read handle and the input write handle. Set
2683 * the inheritance properties to FALSE. Otherwise, the child inherits
2684 * the these handles; resulting in non-closeable handles to the pipes
2685 * being created. */
2686 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002687 GetCurrentProcess(), &hChildStdinWrDup, 0,
2688 FALSE,
2689 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002690 if (!fSuccess)
2691 return win32_error("DuplicateHandle", NULL);
2692
2693 /* Close the inheritable version of ChildStdin
2694 that we're using. */
2695 CloseHandle(hChildStdinWr);
2696
2697 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2698 return win32_error("CreatePipe", NULL);
2699
2700 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002701 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2702 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002703 if (!fSuccess)
2704 return win32_error("DuplicateHandle", NULL);
2705
2706 /* Close the inheritable version of ChildStdout
2707 that we're using. */
2708 CloseHandle(hChildStdoutRd);
2709
2710 if (n != POPEN_4) {
2711 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2712 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002713 fSuccess = DuplicateHandle(GetCurrentProcess(),
2714 hChildStderrRd,
2715 GetCurrentProcess(),
2716 &hChildStderrRdDup, 0,
2717 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002718 if (!fSuccess)
2719 return win32_error("DuplicateHandle", NULL);
2720 /* Close the inheritable version of ChildStdErr that we're using. */
2721 CloseHandle(hChildStderrRd);
2722 }
2723
2724 switch (n) {
2725 case POPEN_1:
2726 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2727 case _O_WRONLY | _O_TEXT:
2728 /* Case for writing to child Stdin in text mode. */
2729 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2730 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002731 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002732 PyFile_SetBufSize(f, 0);
2733 /* We don't care about these pipes anymore, so close them. */
2734 CloseHandle(hChildStdoutRdDup);
2735 CloseHandle(hChildStderrRdDup);
2736 break;
2737
2738 case _O_RDONLY | _O_TEXT:
2739 /* Case for reading from child Stdout in text mode. */
2740 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2741 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002742 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002743 PyFile_SetBufSize(f, 0);
2744 /* We don't care about these pipes anymore, so close them. */
2745 CloseHandle(hChildStdinWrDup);
2746 CloseHandle(hChildStderrRdDup);
2747 break;
2748
2749 case _O_RDONLY | _O_BINARY:
2750 /* Case for readinig from child Stdout in binary mode. */
2751 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2752 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002753 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002754 PyFile_SetBufSize(f, 0);
2755 /* We don't care about these pipes anymore, so close them. */
2756 CloseHandle(hChildStdinWrDup);
2757 CloseHandle(hChildStderrRdDup);
2758 break;
2759
2760 case _O_WRONLY | _O_BINARY:
2761 /* Case for writing to child Stdin in binary mode. */
2762 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2763 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002764 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002765 PyFile_SetBufSize(f, 0);
2766 /* We don't care about these pipes anymore, so close them. */
2767 CloseHandle(hChildStdoutRdDup);
2768 CloseHandle(hChildStderrRdDup);
2769 break;
2770 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002771 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002772 break;
2773
2774 case POPEN_2:
2775 case POPEN_4:
2776 {
2777 char *m1, *m2;
2778 PyObject *p1, *p2;
2779
2780 if (mode && _O_TEXT) {
2781 m1 = "r";
2782 m2 = "w";
2783 } else {
2784 m1 = "rb";
2785 m2 = "wb";
2786 }
2787
2788 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2789 f1 = _fdopen(fd1, m2);
2790 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2791 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002792 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002793 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002794 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002795 PyFile_SetBufSize(p2, 0);
2796
2797 if (n != 4)
2798 CloseHandle(hChildStderrRdDup);
2799
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002800 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002801 Py_XDECREF(p1);
2802 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002803 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002804 break;
2805 }
2806
2807 case POPEN_3:
2808 {
2809 char *m1, *m2;
2810 PyObject *p1, *p2, *p3;
2811
2812 if (mode && _O_TEXT) {
2813 m1 = "r";
2814 m2 = "w";
2815 } else {
2816 m1 = "rb";
2817 m2 = "wb";
2818 }
2819
2820 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2821 f1 = _fdopen(fd1, m2);
2822 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2823 f2 = _fdopen(fd2, m1);
2824 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2825 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002826 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002827 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2828 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002829 PyFile_SetBufSize(p1, 0);
2830 PyFile_SetBufSize(p2, 0);
2831 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002832 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002833 Py_XDECREF(p1);
2834 Py_XDECREF(p2);
2835 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002836 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002837 break;
2838 }
2839 }
2840
2841 if (n == POPEN_4) {
2842 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002843 hChildStdinRd,
2844 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002845 hChildStdoutWr,
2846 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002847 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002848 }
2849 else {
2850 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002851 hChildStdinRd,
2852 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002853 hChildStderrWr,
2854 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002855 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002856 }
2857
Mark Hammondb37a3732000-08-14 04:47:33 +00002858 /*
2859 * Insert the files we've created into the process dictionary
2860 * all referencing the list with the process handle and the
2861 * initial number of files (see description below in _PyPclose).
2862 * Since if _PyPclose later tried to wait on a process when all
2863 * handles weren't closed, it could create a deadlock with the
2864 * child, we spend some energy here to try to ensure that we
2865 * either insert all file handles into the dictionary or none
2866 * at all. It's a little clumsy with the various popen modes
2867 * and variable number of files involved.
2868 */
2869 if (!_PyPopenProcs) {
2870 _PyPopenProcs = PyDict_New();
2871 }
2872
2873 if (_PyPopenProcs) {
2874 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2875 int ins_rc[3];
2876
2877 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2878 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2879
2880 procObj = PyList_New(2);
2881 hProcessObj = PyLong_FromVoidPtr(hProcess);
2882 intObj = PyInt_FromLong(file_count);
2883
2884 if (procObj && hProcessObj && intObj) {
2885 PyList_SetItem(procObj,0,hProcessObj);
2886 PyList_SetItem(procObj,1,intObj);
2887
2888 fileObj[0] = PyLong_FromVoidPtr(f1);
2889 if (fileObj[0]) {
2890 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2891 fileObj[0],
2892 procObj);
2893 }
2894 if (file_count >= 2) {
2895 fileObj[1] = PyLong_FromVoidPtr(f2);
2896 if (fileObj[1]) {
2897 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2898 fileObj[1],
2899 procObj);
2900 }
2901 }
2902 if (file_count >= 3) {
2903 fileObj[2] = PyLong_FromVoidPtr(f3);
2904 if (fileObj[2]) {
2905 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2906 fileObj[2],
2907 procObj);
2908 }
2909 }
2910
2911 if (ins_rc[0] < 0 || !fileObj[0] ||
2912 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2913 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2914 /* Something failed - remove any dictionary
2915 * entries that did make it.
2916 */
2917 if (!ins_rc[0] && fileObj[0]) {
2918 PyDict_DelItem(_PyPopenProcs,
2919 fileObj[0]);
2920 }
2921 if (!ins_rc[1] && fileObj[1]) {
2922 PyDict_DelItem(_PyPopenProcs,
2923 fileObj[1]);
2924 }
2925 if (!ins_rc[2] && fileObj[2]) {
2926 PyDict_DelItem(_PyPopenProcs,
2927 fileObj[2]);
2928 }
2929 }
2930 }
2931
2932 /*
2933 * Clean up our localized references for the dictionary keys
2934 * and value since PyDict_SetItem will Py_INCREF any copies
2935 * that got placed in the dictionary.
2936 */
2937 Py_XDECREF(procObj);
2938 Py_XDECREF(fileObj[0]);
2939 Py_XDECREF(fileObj[1]);
2940 Py_XDECREF(fileObj[2]);
2941 }
2942
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002943 /* Child is launched. Close the parents copy of those pipe
2944 * handles that only the child should have open. You need to
2945 * make sure that no handles to the write end of the output pipe
2946 * are maintained in this process or else the pipe will not close
2947 * when the child process exits and the ReadFile will hang. */
2948
2949 if (!CloseHandle(hChildStdinRd))
2950 return win32_error("CloseHandle", NULL);
2951
2952 if (!CloseHandle(hChildStdoutWr))
2953 return win32_error("CloseHandle", NULL);
2954
2955 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2956 return win32_error("CloseHandle", NULL);
2957
2958 return f;
2959}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002960
2961/*
2962 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2963 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002964 *
2965 * This function uses the _PyPopenProcs dictionary in order to map the
2966 * input file pointer to information about the process that was
2967 * originally created by the popen* call that created the file pointer.
2968 * The dictionary uses the file pointer as a key (with one entry
2969 * inserted for each file returned by the original popen* call) and a
2970 * single list object as the value for all files from a single call.
2971 * The list object contains the Win32 process handle at [0], and a file
2972 * count at [1], which is initialized to the total number of file
2973 * handles using that list.
2974 *
2975 * This function closes whichever handle it is passed, and decrements
2976 * the file count in the dictionary for the process handle pointed to
2977 * by this file. On the last close (when the file count reaches zero),
2978 * this function will wait for the child process and then return its
2979 * exit code as the result of the close() operation. This permits the
2980 * files to be closed in any order - it is always the close() of the
2981 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002982 */
Tim Peters736aa322000-09-01 06:51:24 +00002983
2984 /* RED_FLAG 31-Aug-2000 Tim
2985 * This is always called (today!) between a pair of
2986 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2987 * macros. So the thread running this has no valid thread state, as
2988 * far as Python is concerned. However, this calls some Python API
2989 * functions that cannot be called safely without a valid thread
2990 * state, in particular PyDict_GetItem.
2991 * As a temporary hack (although it may last for years ...), we
2992 * *rely* on not having a valid thread state in this function, in
2993 * order to create our own "from scratch".
2994 * This will deadlock if _PyPclose is ever called by a thread
2995 * holding the global lock.
2996 */
2997
Fredrik Lundh56055a42000-07-23 19:47:12 +00002998static int _PyPclose(FILE *file)
2999{
Fredrik Lundh20318932000-07-26 17:29:12 +00003000 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003001 DWORD exit_code;
3002 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003003 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3004 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003005#ifdef WITH_THREAD
3006 PyInterpreterState* pInterpreterState;
3007 PyThreadState* pThreadState;
3008#endif
3009
Fredrik Lundh20318932000-07-26 17:29:12 +00003010 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003011 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003012 */
3013 result = fclose(file);
3014
Tim Peters736aa322000-09-01 06:51:24 +00003015#ifdef WITH_THREAD
3016 /* Bootstrap a valid thread state into existence. */
3017 pInterpreterState = PyInterpreterState_New();
3018 if (!pInterpreterState) {
3019 /* Well, we're hosed now! We don't have a thread
3020 * state, so can't call a nice error routine, or raise
3021 * an exception. Just die.
3022 */
3023 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003024 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003025 return -1; /* unreachable */
3026 }
3027 pThreadState = PyThreadState_New(pInterpreterState);
3028 if (!pThreadState) {
3029 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003030 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003031 return -1; /* unreachable */
3032 }
3033 /* Grab the global lock. Note that this will deadlock if the
3034 * current thread already has the lock! (see RED_FLAG comments
3035 * before this function)
3036 */
3037 PyEval_RestoreThread(pThreadState);
3038#endif
3039
Fredrik Lundh56055a42000-07-23 19:47:12 +00003040 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003041 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3042 (procObj = PyDict_GetItem(_PyPopenProcs,
3043 fileObj)) != NULL &&
3044 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3045 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3046
3047 hProcess = PyLong_AsVoidPtr(hProcessObj);
3048 file_count = PyInt_AsLong(intObj);
3049
3050 if (file_count > 1) {
3051 /* Still other files referencing process */
3052 file_count--;
3053 PyList_SetItem(procObj,1,
3054 PyInt_FromLong(file_count));
3055 } else {
3056 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003057 if (result != EOF &&
3058 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3059 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003060 /* Possible truncation here in 16-bit environments, but
3061 * real exit codes are just the lower byte in any event.
3062 */
3063 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003064 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003065 /* Indicate failure - this will cause the file object
3066 * to raise an I/O error and translate the last Win32
3067 * error code from errno. We do have a problem with
3068 * last errors that overlap the normal errno table,
3069 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003070 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003071 if (result != EOF) {
3072 /* If the error wasn't from the fclose(), then
3073 * set errno for the file object error handling.
3074 */
3075 errno = GetLastError();
3076 }
3077 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003078 }
3079
3080 /* Free up the native handle at this point */
3081 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003082 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003083
Mark Hammondb37a3732000-08-14 04:47:33 +00003084 /* Remove this file pointer from dictionary */
3085 PyDict_DelItem(_PyPopenProcs, fileObj);
3086
3087 if (PyDict_Size(_PyPopenProcs) == 0) {
3088 Py_DECREF(_PyPopenProcs);
3089 _PyPopenProcs = NULL;
3090 }
3091
3092 } /* if object retrieval ok */
3093
3094 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003095 } /* if _PyPopenProcs */
3096
Tim Peters736aa322000-09-01 06:51:24 +00003097#ifdef WITH_THREAD
3098 /* Tear down the thread & interpreter states.
3099 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003100 * call the thread clear & delete functions, and indeed insist on
3101 * doing that themselves. The lock must be held during the clear, but
3102 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003103 */
3104 PyInterpreterState_Clear(pInterpreterState);
3105 PyEval_ReleaseThread(pThreadState);
3106 PyInterpreterState_Delete(pInterpreterState);
3107#endif
3108
Fredrik Lundh56055a42000-07-23 19:47:12 +00003109 return result;
3110}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003111
3112#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003114posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003115{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003116 char *name;
3117 char *mode = "r";
3118 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003119 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003120 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003121 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003122 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003123 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003124 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003125 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003126 if (fp == NULL)
3127 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003128 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003129 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003130 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003131 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003132}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003133#endif
3134
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003135#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003137
Guido van Rossumb6775db1994-08-01 11:34:53 +00003138#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003139static char posix_setuid__doc__[] =
3140"setuid(uid) -> None\n\
3141Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003143posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003144{
3145 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003146 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003147 return NULL;
3148 if (setuid(uid) < 0)
3149 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003150 Py_INCREF(Py_None);
3151 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003152}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003153#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003156#ifdef HAVE_SETEUID
3157static char posix_seteuid__doc__[] =
3158"seteuid(uid) -> None\n\
3159Set the current process's effective user id.";
3160static PyObject *
3161posix_seteuid (PyObject *self, PyObject *args)
3162{
3163 int euid;
3164 if (!PyArg_ParseTuple(args, "i", &euid)) {
3165 return NULL;
3166 } else if (seteuid(euid) < 0) {
3167 return posix_error();
3168 } else {
3169 Py_INCREF(Py_None);
3170 return Py_None;
3171 }
3172}
3173#endif /* HAVE_SETEUID */
3174
3175#ifdef HAVE_SETEGID
3176static char posix_setegid__doc__[] =
3177"setegid(gid) -> None\n\
3178Set the current process's effective group id.";
3179static PyObject *
3180posix_setegid (PyObject *self, PyObject *args)
3181{
3182 int egid;
3183 if (!PyArg_ParseTuple(args, "i", &egid)) {
3184 return NULL;
3185 } else if (setegid(egid) < 0) {
3186 return posix_error();
3187 } else {
3188 Py_INCREF(Py_None);
3189 return Py_None;
3190 }
3191}
3192#endif /* HAVE_SETEGID */
3193
3194#ifdef HAVE_SETREUID
3195static char posix_setreuid__doc__[] =
3196"seteuid(ruid, euid) -> None\n\
3197Set the current process's real and effective user ids.";
3198static PyObject *
3199posix_setreuid (PyObject *self, PyObject *args)
3200{
3201 int ruid, euid;
3202 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3203 return NULL;
3204 } else if (setreuid(ruid, euid) < 0) {
3205 return posix_error();
3206 } else {
3207 Py_INCREF(Py_None);
3208 return Py_None;
3209 }
3210}
3211#endif /* HAVE_SETREUID */
3212
3213#ifdef HAVE_SETREGID
3214static char posix_setregid__doc__[] =
3215"setegid(rgid, egid) -> None\n\
3216Set the current process's real and effective group ids.";
3217static PyObject *
3218posix_setregid (PyObject *self, PyObject *args)
3219{
3220 int rgid, egid;
3221 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3222 return NULL;
3223 } else if (setregid(rgid, egid) < 0) {
3224 return posix_error();
3225 } else {
3226 Py_INCREF(Py_None);
3227 return Py_None;
3228 }
3229}
3230#endif /* HAVE_SETREGID */
3231
Guido van Rossumb6775db1994-08-01 11:34:53 +00003232#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003233static char posix_setgid__doc__[] =
3234"setgid(gid) -> None\n\
3235Set the current process's group id.";
3236
Barry Warsaw53699e91996-12-10 23:23:01 +00003237static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003238posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003239{
3240 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003241 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003242 return NULL;
3243 if (setgid(gid) < 0)
3244 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003245 Py_INCREF(Py_None);
3246 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003247}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003248#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003249
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003250#ifdef HAVE_SETGROUPS
3251static char posix_setgroups__doc__[] =
3252"setgroups(list) -> None\n\
3253Set the groups of the current process to list.";
3254
3255static PyObject *
3256posix_setgroups(PyObject *self, PyObject *args)
3257{
3258 PyObject *groups;
3259 int i, len;
3260 gid_t grouplist[MAX_GROUPS];
3261
3262 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3263 return NULL;
3264 if (!PySequence_Check(groups)) {
3265 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3266 return NULL;
3267 }
3268 len = PySequence_Size(groups);
3269 if (len > MAX_GROUPS) {
3270 PyErr_SetString(PyExc_ValueError, "too many groups");
3271 return NULL;
3272 }
3273 for(i = 0; i < len; i++) {
3274 PyObject *elem;
3275 elem = PySequence_GetItem(groups, i);
3276 if (!elem)
3277 return NULL;
3278 if (!PyInt_Check(elem)) {
3279 PyErr_SetString(PyExc_TypeError,
3280 "groups must be integers");
3281 Py_DECREF(elem);
3282 return NULL;
3283 }
3284 /* XXX: check that value fits into gid_t. */
3285 grouplist[i] = PyInt_AsLong(elem);
3286 Py_DECREF(elem);
3287 }
3288
3289 if (setgroups(len, grouplist) < 0)
3290 return posix_error();
3291 Py_INCREF(Py_None);
3292 return Py_None;
3293}
3294#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003295
Guido van Rossumb6775db1994-08-01 11:34:53 +00003296#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003297static char posix_waitpid__doc__[] =
3298"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003299Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003300
Barry Warsaw53699e91996-12-10 23:23:01 +00003301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003302posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003303{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003304 int pid, options;
3305#ifdef UNION_WAIT
3306 union wait status;
3307#define status_i (status.w_status)
3308#else
3309 int status;
3310#define status_i status
3311#endif
3312 status_i = 0;
3313
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003314 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003315 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003316 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003317#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003318 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003319#else
3320 pid = waitpid(pid, &status, options);
3321#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003322 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003323 if (pid == -1)
3324 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003325 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003326 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003327}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003328#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003329
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003330
Guido van Rossumad0ee831995-03-01 10:34:45 +00003331#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003332static char posix_wait__doc__[] =
3333"wait() -> (pid, status)\n\
3334Wait for completion of a child process.";
3335
Barry Warsaw53699e91996-12-10 23:23:01 +00003336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003337posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003338{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003339 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003340#ifdef UNION_WAIT
3341 union wait status;
3342#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003343#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003344 int status;
3345#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003346#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003347 if (!PyArg_ParseTuple(args, ":wait"))
3348 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003349 status_i = 0;
3350 Py_BEGIN_ALLOW_THREADS
3351 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003352 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003353 if (pid == -1)
3354 return posix_error();
3355 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003356 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003357#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003358}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003359#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003360
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003361
3362static char posix_lstat__doc__[] =
3363"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3364Like stat(path), but do not follow symbolic links.";
3365
Barry Warsaw53699e91996-12-10 23:23:01 +00003366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003367posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003368{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003369#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003370 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003371#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003372 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003373#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003374}
3375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003376
Guido van Rossumb6775db1994-08-01 11:34:53 +00003377#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003378static char posix_readlink__doc__[] =
3379"readlink(path) -> path\n\
3380Return a string representing the path to which the symbolic link points.";
3381
Barry Warsaw53699e91996-12-10 23:23:01 +00003382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003383posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003384{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003385 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003386 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003387 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003388 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003389 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003390 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003391 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003392 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003393 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003394 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003395 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003396}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003397#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003399
Guido van Rossumb6775db1994-08-01 11:34:53 +00003400#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003401static char posix_symlink__doc__[] =
3402"symlink(src, dst) -> None\n\
3403Create a symbolic link.";
3404
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003406posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003407{
Mark Hammondef8b6542001-05-13 08:04:26 +00003408 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003409}
3410#endif /* HAVE_SYMLINK */
3411
3412
3413#ifdef HAVE_TIMES
3414#ifndef HZ
3415#define HZ 60 /* Universal constant :-) */
3416#endif /* HZ */
3417
Guido van Rossumd48f2521997-12-05 22:19:34 +00003418#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3419static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003420system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003421{
3422 ULONG value = 0;
3423
3424 Py_BEGIN_ALLOW_THREADS
3425 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3426 Py_END_ALLOW_THREADS
3427
3428 return value;
3429}
3430
3431static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003432posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003433{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003434 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003435 return NULL;
3436
3437 /* Currently Only Uptime is Provided -- Others Later */
3438 return Py_BuildValue("ddddd",
3439 (double)0 /* t.tms_utime / HZ */,
3440 (double)0 /* t.tms_stime / HZ */,
3441 (double)0 /* t.tms_cutime / HZ */,
3442 (double)0 /* t.tms_cstime / HZ */,
3443 (double)system_uptime() / 1000);
3444}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003445#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003447posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003448{
3449 struct tms t;
3450 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003451 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003452 return NULL;
3453 errno = 0;
3454 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003455 if (c == (clock_t) -1)
3456 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003457 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003458 (double)t.tms_utime / HZ,
3459 (double)t.tms_stime / HZ,
3460 (double)t.tms_cutime / HZ,
3461 (double)t.tms_cstime / HZ,
3462 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003463}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003464#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003465#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003466
3467
Guido van Rossum87755a21996-09-07 00:59:43 +00003468#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003469#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003471posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003472{
3473 FILETIME create, exit, kernel, user;
3474 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003475 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003476 return NULL;
3477 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003478 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3479 /* The fields of a FILETIME structure are the hi and lo part
3480 of a 64-bit value expressed in 100 nanosecond units.
3481 1e7 is one second in such units; 1e-7 the inverse.
3482 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3483 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003484 return Py_BuildValue(
3485 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003486 (double)(kernel.dwHighDateTime*429.4967296 +
3487 kernel.dwLowDateTime*1e-7),
3488 (double)(user.dwHighDateTime*429.4967296 +
3489 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003490 (double)0,
3491 (double)0,
3492 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003493}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003494#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003495
3496#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003497static char posix_times__doc__[] =
3498"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3499Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003500#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003501
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003502
Guido van Rossumb6775db1994-08-01 11:34:53 +00003503#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003504static char posix_setsid__doc__[] =
3505"setsid() -> None\n\
3506Call the system call setsid().";
3507
Barry Warsaw53699e91996-12-10 23:23:01 +00003508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003509posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003510{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003511 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003512 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003513 if (setsid() < 0)
3514 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003515 Py_INCREF(Py_None);
3516 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003517}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003518#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003519
Guido van Rossumb6775db1994-08-01 11:34:53 +00003520#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003521static char posix_setpgid__doc__[] =
3522"setpgid(pid, pgrp) -> None\n\
3523Call the system call setpgid().";
3524
Barry Warsaw53699e91996-12-10 23:23:01 +00003525static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003526posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003527{
3528 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003529 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003530 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003531 if (setpgid(pid, pgrp) < 0)
3532 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003533 Py_INCREF(Py_None);
3534 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003535}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003536#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003537
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003538
Guido van Rossumb6775db1994-08-01 11:34:53 +00003539#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003540static char posix_tcgetpgrp__doc__[] =
3541"tcgetpgrp(fd) -> pgid\n\
3542Return the process group associated with the terminal given by a fd.";
3543
Barry Warsaw53699e91996-12-10 23:23:01 +00003544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003545posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003546{
3547 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003548 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003549 return NULL;
3550 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003551 if (pgid < 0)
3552 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003553 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003554}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003555#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003556
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003557
Guido van Rossumb6775db1994-08-01 11:34:53 +00003558#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003559static char posix_tcsetpgrp__doc__[] =
3560"tcsetpgrp(fd, pgid) -> None\n\
3561Set the process group associated with the terminal given by a fd.";
3562
Barry Warsaw53699e91996-12-10 23:23:01 +00003563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003564posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003565{
3566 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003567 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003568 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003569 if (tcsetpgrp(fd, pgid) < 0)
3570 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003571 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003572 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003573}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003574#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003575
Guido van Rossum687dd131993-05-17 08:34:16 +00003576/* Functions acting on file descriptors */
3577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003578static char posix_open__doc__[] =
3579"open(filename, flag [, mode=0777]) -> fd\n\
3580Open a file (for low level IO).";
3581
Barry Warsaw53699e91996-12-10 23:23:01 +00003582static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003583posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003584{
Mark Hammondef8b6542001-05-13 08:04:26 +00003585 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003586 int flag;
3587 int mode = 0777;
3588 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003589 if (!PyArg_ParseTuple(args, "eti|i",
3590 Py_FileSystemDefaultEncoding, &file,
3591 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003592 return NULL;
3593
Barry Warsaw53699e91996-12-10 23:23:01 +00003594 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003595 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003596 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003597 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003598 return posix_error_with_allocated_filename(file);
3599 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003600 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003601}
3602
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003603
3604static char posix_close__doc__[] =
3605"close(fd) -> None\n\
3606Close a file descriptor (for low level IO).";
3607
Barry Warsaw53699e91996-12-10 23:23:01 +00003608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003609posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003610{
3611 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003612 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003613 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003614 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003615 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003616 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003617 if (res < 0)
3618 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003619 Py_INCREF(Py_None);
3620 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003621}
3622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003623
3624static char posix_dup__doc__[] =
3625"dup(fd) -> fd2\n\
3626Return a duplicate of a file descriptor.";
3627
Barry Warsaw53699e91996-12-10 23:23:01 +00003628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003629posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003630{
3631 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003632 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003633 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003634 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003635 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003636 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003637 if (fd < 0)
3638 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003639 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003640}
3641
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003642
3643static char posix_dup2__doc__[] =
3644"dup2(fd, fd2) -> None\n\
3645Duplicate file descriptor.";
3646
Barry Warsaw53699e91996-12-10 23:23:01 +00003647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003648posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003649{
3650 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003651 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003652 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003653 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003654 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003655 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003656 if (res < 0)
3657 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003658 Py_INCREF(Py_None);
3659 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003660}
3661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003662
3663static char posix_lseek__doc__[] =
3664"lseek(fd, pos, how) -> newpos\n\
3665Set the current position of a file descriptor.";
3666
Barry Warsaw53699e91996-12-10 23:23:01 +00003667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003668posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003669{
3670 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003671#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003672 LONG_LONG pos, res;
3673#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003674 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003675#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003676 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003677 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003678 return NULL;
3679#ifdef SEEK_SET
3680 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3681 switch (how) {
3682 case 0: how = SEEK_SET; break;
3683 case 1: how = SEEK_CUR; break;
3684 case 2: how = SEEK_END; break;
3685 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003686#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003687
3688#if !defined(HAVE_LARGEFILE_SUPPORT)
3689 pos = PyInt_AsLong(posobj);
3690#else
3691 pos = PyLong_Check(posobj) ?
3692 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3693#endif
3694 if (PyErr_Occurred())
3695 return NULL;
3696
Barry Warsaw53699e91996-12-10 23:23:01 +00003697 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003698#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003699 res = _lseeki64(fd, pos, how);
3700#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003701 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003702#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003703 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003704 if (res < 0)
3705 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003706
3707#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003708 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003709#else
3710 return PyLong_FromLongLong(res);
3711#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003712}
3713
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003714
3715static char posix_read__doc__[] =
3716"read(fd, buffersize) -> string\n\
3717Read a file descriptor.";
3718
Barry Warsaw53699e91996-12-10 23:23:01 +00003719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003720posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003721{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003722 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003723 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003724 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003725 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003726 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003727 if (buffer == NULL)
3728 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003729 Py_BEGIN_ALLOW_THREADS
3730 n = read(fd, PyString_AsString(buffer), size);
3731 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003732 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003733 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003734 return posix_error();
3735 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003736 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003737 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003738 return buffer;
3739}
3740
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003741
3742static char posix_write__doc__[] =
3743"write(fd, string) -> byteswritten\n\
3744Write a string to a file descriptor.";
3745
Barry Warsaw53699e91996-12-10 23:23:01 +00003746static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003747posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003748{
3749 int fd, size;
3750 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003751 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003752 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003753 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003754 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003755 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003756 if (size < 0)
3757 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003758 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003759}
3760
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003761
3762static char posix_fstat__doc__[]=
3763"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3764Like stat(), but for an open file descriptor.";
3765
Barry Warsaw53699e91996-12-10 23:23:01 +00003766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003767posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003768{
3769 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003770 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003771 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003772 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003773 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003774 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003775 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003776 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003777 if (res != 0)
3778 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003779
3780 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003781}
3782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003783
3784static char posix_fdopen__doc__[] =
3785"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3786Return an open file object connected to a file descriptor.";
3787
Barry Warsaw53699e91996-12-10 23:23:01 +00003788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003789posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003790{
Guido van Rossum687dd131993-05-17 08:34:16 +00003791 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003792 char *mode = "r";
3793 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003794 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003795 PyObject *f;
3796 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003797 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003798
Barry Warsaw53699e91996-12-10 23:23:01 +00003799 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003800 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003801 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003802 if (fp == NULL)
3803 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003804 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003805 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003806 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003807 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003808}
3809
Skip Montanaro1517d842000-07-19 14:34:14 +00003810static char posix_isatty__doc__[] =
3811"isatty(fd) -> Boolean\n\
3812Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003813connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003814
3815static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003816posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003817{
3818 int fd;
3819 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3820 return NULL;
3821 return Py_BuildValue("i", isatty(fd));
3822}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003823
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003824#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003825static char posix_pipe__doc__[] =
3826"pipe() -> (read_end, write_end)\n\
3827Create a pipe.";
3828
Barry Warsaw53699e91996-12-10 23:23:01 +00003829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003830posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003831{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003832#if defined(PYOS_OS2)
3833 HFILE read, write;
3834 APIRET rc;
3835
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003836 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003837 return NULL;
3838
3839 Py_BEGIN_ALLOW_THREADS
3840 rc = DosCreatePipe( &read, &write, 4096);
3841 Py_END_ALLOW_THREADS
3842 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003843 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003844
3845 return Py_BuildValue("(ii)", read, write);
3846#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003847#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003848 int fds[2];
3849 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003850 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003851 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003852 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003853 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003854 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003855 if (res != 0)
3856 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003857 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003858#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003859 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003860 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003861 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003862 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003863 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003864 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003865 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003866 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003867 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003868 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003869 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3870 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003871 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003872#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003873#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003874}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003875#endif /* HAVE_PIPE */
3876
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003877
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003878#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003879static char posix_mkfifo__doc__[] =
3880"mkfifo(file, [, mode=0666]) -> None\n\
3881Create a FIFO (a POSIX named pipe).";
3882
Barry Warsaw53699e91996-12-10 23:23:01 +00003883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003884posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003885{
3886 char *file;
3887 int mode = 0666;
3888 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003889 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003890 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003891 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003892 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003893 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003894 if (res < 0)
3895 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003896 Py_INCREF(Py_None);
3897 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003898}
3899#endif
3900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003901
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003902#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003903static char posix_ftruncate__doc__[] =
3904"ftruncate(fd, length) -> None\n\
3905Truncate a file to a specified length.";
3906
Barry Warsaw53699e91996-12-10 23:23:01 +00003907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003908posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003909{
3910 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003911 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003912 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003913 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003914
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003915 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003916 return NULL;
3917
3918#if !defined(HAVE_LARGEFILE_SUPPORT)
3919 length = PyInt_AsLong(lenobj);
3920#else
3921 length = PyLong_Check(lenobj) ?
3922 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3923#endif
3924 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003925 return NULL;
3926
Barry Warsaw53699e91996-12-10 23:23:01 +00003927 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003928 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003929 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003930 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003931 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003932 return NULL;
3933 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003934 Py_INCREF(Py_None);
3935 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003936}
3937#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003938
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003939#ifdef NeXT
3940#define HAVE_PUTENV
3941/* Steve Spicklemire got this putenv from NeXTAnswers */
3942static int
3943putenv(char *newval)
3944{
3945 extern char **environ;
3946
3947 static int firstTime = 1;
3948 char **ep;
3949 char *cp;
3950 int esiz;
3951 char *np;
3952
3953 if (!(np = strchr(newval, '=')))
3954 return 1;
3955 *np = '\0';
3956
3957 /* look it up */
3958 for (ep=environ ; *ep ; ep++)
3959 {
3960 /* this should always be true... */
3961 if (cp = strchr(*ep, '='))
3962 {
3963 *cp = '\0';
3964 if (!strcmp(*ep, newval))
3965 {
3966 /* got it! */
3967 *cp = '=';
3968 break;
3969 }
3970 *cp = '=';
3971 }
3972 else
3973 {
3974 *np = '=';
3975 return 1;
3976 }
3977 }
3978
3979 *np = '=';
3980 if (*ep)
3981 {
3982 /* the string was already there:
3983 just replace it with the new one */
3984 *ep = newval;
3985 return 0;
3986 }
3987
3988 /* expand environ by one */
3989 for (esiz=2, ep=environ ; *ep ; ep++)
3990 esiz++;
3991 if (firstTime)
3992 {
3993 char **epp;
3994 char **newenv;
3995 if (!(newenv = malloc(esiz * sizeof(char *))))
3996 return 1;
3997
3998 for (ep=environ, epp=newenv ; *ep ;)
3999 *epp++ = *ep++;
4000 *epp++ = newval;
4001 *epp = (char *) 0;
4002 environ = newenv;
4003 }
4004 else
4005 {
4006 if (!(environ = realloc(environ, esiz * sizeof(char *))))
4007 return 1;
4008 environ[esiz - 2] = newval;
4009 environ[esiz - 1] = (char *) 0;
4010 firstTime = 0;
4011 }
4012
4013 return 0;
4014}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00004015#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004017
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004018#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004019static char posix_putenv__doc__[] =
4020"putenv(key, value) -> None\n\
4021Change or add an environment variable.";
4022
Fred Drake762e2061999-08-26 17:23:54 +00004023/* Save putenv() parameters as values here, so we can collect them when they
4024 * get re-set with another call for the same key. */
4025static PyObject *posix_putenv_garbage;
4026
Barry Warsaw53699e91996-12-10 23:23:01 +00004027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004028posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004029{
4030 char *s1, *s2;
4031 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004032 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004033
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004034 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004035 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004036
4037#if defined(PYOS_OS2)
4038 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4039 APIRET rc;
4040
4041 if (strlen(s2) == 0) /* If New Value is an Empty String */
4042 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4043
4044 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4045 if (rc != NO_ERROR)
4046 return os2_error(rc);
4047
4048 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4049 APIRET rc;
4050
4051 if (strlen(s2) == 0) /* If New Value is an Empty String */
4052 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4053
4054 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4055 if (rc != NO_ERROR)
4056 return os2_error(rc);
4057 } else {
4058#endif
4059
Fred Drake762e2061999-08-26 17:23:54 +00004060 /* XXX This can leak memory -- not easy to fix :-( */
4061 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
4062 if (newstr == NULL)
4063 return PyErr_NoMemory();
4064 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004065 (void) sprintf(new, "%s=%s", s1, s2);
4066 if (putenv(new)) {
4067 posix_error();
4068 return NULL;
4069 }
Fred Drake762e2061999-08-26 17:23:54 +00004070 /* Install the first arg and newstr in posix_putenv_garbage;
4071 * this will cause previous value to be collected. This has to
4072 * happen after the real putenv() call because the old value
4073 * was still accessible until then. */
4074 if (PyDict_SetItem(posix_putenv_garbage,
4075 PyTuple_GET_ITEM(args, 0), newstr)) {
4076 /* really not much we can do; just leak */
4077 PyErr_Clear();
4078 }
4079 else {
4080 Py_DECREF(newstr);
4081 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004082
4083#if defined(PYOS_OS2)
4084 }
4085#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004086 Py_INCREF(Py_None);
4087 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004088}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004089#endif /* putenv */
4090
Guido van Rossumc524d952001-10-19 01:31:59 +00004091#ifdef HAVE_UNSETENV
4092static char posix_unsetenv__doc__[] =
4093"unsetenv(key) -> None\n\
4094Delete an environment variable.";
4095
4096static PyObject *
4097posix_unsetenv(PyObject *self, PyObject *args)
4098{
4099 char *s1;
4100
4101 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4102 return NULL;
4103
4104 unsetenv(s1);
4105
4106 /* Remove the key from posix_putenv_garbage;
4107 * this will cause it to be collected. This has to
4108 * happen after the real unsetenv() call because the
4109 * old value was still accessible until then.
4110 */
4111 if (PyDict_DelItem(posix_putenv_garbage,
4112 PyTuple_GET_ITEM(args, 0))) {
4113 /* really not much we can do; just leak */
4114 PyErr_Clear();
4115 }
4116
4117 Py_INCREF(Py_None);
4118 return Py_None;
4119}
4120#endif /* unsetenv */
4121
Guido van Rossumb6a47161997-09-15 22:54:34 +00004122#ifdef HAVE_STRERROR
4123static char posix_strerror__doc__[] =
4124"strerror(code) -> string\n\
4125Translate an error code to a message string.";
4126
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004128posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004129{
4130 int code;
4131 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004132 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004133 return NULL;
4134 message = strerror(code);
4135 if (message == NULL) {
4136 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004137 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004138 return NULL;
4139 }
4140 return PyString_FromString(message);
4141}
4142#endif /* strerror */
4143
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004144
Guido van Rossumc9641791998-08-04 15:26:23 +00004145#ifdef HAVE_SYS_WAIT_H
4146
4147#ifdef WIFSTOPPED
4148static char posix_WIFSTOPPED__doc__[] =
4149"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004150Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004151
4152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004153posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004154{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004155#ifdef UNION_WAIT
4156 union wait status;
4157#define status_i (status.w_status)
4158#else
4159 int status;
4160#define status_i status
4161#endif
4162 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004163
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004164 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004165 {
4166 return NULL;
4167 }
4168
4169 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004170#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004171}
4172#endif /* WIFSTOPPED */
4173
4174#ifdef WIFSIGNALED
4175static char posix_WIFSIGNALED__doc__[] =
4176"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004177Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004178
4179static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004180posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004181{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004182#ifdef UNION_WAIT
4183 union wait status;
4184#define status_i (status.w_status)
4185#else
4186 int status;
4187#define status_i status
4188#endif
4189 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004190
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004191 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004192 {
4193 return NULL;
4194 }
4195
4196 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004197#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004198}
4199#endif /* WIFSIGNALED */
4200
4201#ifdef WIFEXITED
4202static char posix_WIFEXITED__doc__[] =
4203"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004204Return true if the process returning 'status' exited using the exit()\n\
4205system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004206
4207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004208posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004209{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004210#ifdef UNION_WAIT
4211 union wait status;
4212#define status_i (status.w_status)
4213#else
4214 int status;
4215#define status_i status
4216#endif
4217 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004218
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004219 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004220 {
4221 return NULL;
4222 }
4223
4224 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004225#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004226}
4227#endif /* WIFEXITED */
4228
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004229#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004230static char posix_WEXITSTATUS__doc__[] =
4231"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004232Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004233
4234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004235posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004236{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004237#ifdef UNION_WAIT
4238 union wait status;
4239#define status_i (status.w_status)
4240#else
4241 int status;
4242#define status_i status
4243#endif
4244 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004245
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004246 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004247 {
4248 return NULL;
4249 }
4250
4251 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004252#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004253}
4254#endif /* WEXITSTATUS */
4255
4256#ifdef WTERMSIG
4257static char posix_WTERMSIG__doc__[] =
4258"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004259Return the signal that terminated the process that provided the 'status'\n\
4260value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004261
4262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004263posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004264{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004265#ifdef UNION_WAIT
4266 union wait status;
4267#define status_i (status.w_status)
4268#else
4269 int status;
4270#define status_i status
4271#endif
4272 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004273
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004274 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004275 {
4276 return NULL;
4277 }
4278
4279 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004280#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004281}
4282#endif /* WTERMSIG */
4283
4284#ifdef WSTOPSIG
4285static char posix_WSTOPSIG__doc__[] =
4286"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004287Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004288
4289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004290posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004291{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004292#ifdef UNION_WAIT
4293 union wait status;
4294#define status_i (status.w_status)
4295#else
4296 int status;
4297#define status_i status
4298#endif
4299 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004300
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004301 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004302 {
4303 return NULL;
4304 }
4305
4306 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004307#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004308}
4309#endif /* WSTOPSIG */
4310
4311#endif /* HAVE_SYS_WAIT_H */
4312
4313
Guido van Rossum94f6f721999-01-06 18:42:14 +00004314#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004315#ifdef _SCO_DS
4316/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4317 needed definitions in sys/statvfs.h */
4318#define _SVID3
4319#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004320#include <sys/statvfs.h>
4321
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004322static PyObject*
4323_pystatvfs_fromstructstatvfs(struct statvfs st) {
4324 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4325 if (v == NULL)
4326 return NULL;
4327
4328#if !defined(HAVE_LARGEFILE_SUPPORT)
4329 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4330 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4331 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4332 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4333 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4334 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4335 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4336 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4337 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4338 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4339#else
4340 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4341 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4342 PyStructSequence_SET_ITEM(v, 2,
4343 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
4344 PyStructSequence_SET_ITEM(v, 3,
4345 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4346 PyStructSequence_SET_ITEM(v, 4,
4347 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
4348 PyStructSequence_SET_ITEM(v, 5,
4349 PyLong_FromLongLong((LONG_LONG) st.f_files));
4350 PyStructSequence_SET_ITEM(v, 6,
4351 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
4352 PyStructSequence_SET_ITEM(v, 7,
4353 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4354 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4355 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4356#endif
4357
4358 return v;
4359}
4360
Guido van Rossum94f6f721999-01-06 18:42:14 +00004361static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004362"fstatvfs(fd) -> \n\
4363 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004364Perform an fstatvfs system call on the given fd.";
4365
4366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004367posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004368{
4369 int fd, res;
4370 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004371
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004372 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004373 return NULL;
4374 Py_BEGIN_ALLOW_THREADS
4375 res = fstatvfs(fd, &st);
4376 Py_END_ALLOW_THREADS
4377 if (res != 0)
4378 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004379
4380 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004381}
4382#endif /* HAVE_FSTATVFS */
4383
4384
4385#if defined(HAVE_STATVFS)
4386#include <sys/statvfs.h>
4387
4388static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004389"statvfs(path) -> \n\
4390 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004391Perform a statvfs system call on the given path.";
4392
4393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004394posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004395{
4396 char *path;
4397 int res;
4398 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004399 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004400 return NULL;
4401 Py_BEGIN_ALLOW_THREADS
4402 res = statvfs(path, &st);
4403 Py_END_ALLOW_THREADS
4404 if (res != 0)
4405 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004406
4407 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004408}
4409#endif /* HAVE_STATVFS */
4410
4411
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004412#ifdef HAVE_TEMPNAM
4413static char posix_tempnam__doc__[] = "\
4414tempnam([dir[, prefix]]) -> string\n\
4415Return a unique name for a temporary file.\n\
4416The directory and a short may be specified as strings; they may be omitted\n\
4417or None if not needed.";
4418
4419static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004420posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004421{
4422 PyObject *result = NULL;
4423 char *dir = NULL;
4424 char *pfx = NULL;
4425 char *name;
4426
4427 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4428 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004429
4430 if (PyErr_Warn(PyExc_RuntimeWarning,
4431 "tempnam is a potential security risk to your program") < 0)
4432 return NULL;
4433
Fred Drake78b71c22001-07-17 20:37:36 +00004434#ifdef MS_WIN32
4435 name = _tempnam(dir, pfx);
4436#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004437 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004438#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004439 if (name == NULL)
4440 return PyErr_NoMemory();
4441 result = PyString_FromString(name);
4442 free(name);
4443 return result;
4444}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004445#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004446
4447
4448#ifdef HAVE_TMPFILE
4449static char posix_tmpfile__doc__[] = "\
4450tmpfile() -> file object\n\
4451Create a temporary file with no directory entries.";
4452
4453static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004454posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004455{
4456 FILE *fp;
4457
4458 if (!PyArg_ParseTuple(args, ":tmpfile"))
4459 return NULL;
4460 fp = tmpfile();
4461 if (fp == NULL)
4462 return posix_error();
4463 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4464}
4465#endif
4466
4467
4468#ifdef HAVE_TMPNAM
4469static char posix_tmpnam__doc__[] = "\
4470tmpnam() -> string\n\
4471Return a unique name for a temporary file.";
4472
4473static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004474posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004475{
4476 char buffer[L_tmpnam];
4477 char *name;
4478
4479 if (!PyArg_ParseTuple(args, ":tmpnam"))
4480 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004481
4482 if (PyErr_Warn(PyExc_RuntimeWarning,
4483 "tmpnam is a potential security risk to your program") < 0)
4484 return NULL;
4485
Greg Wardb48bc172000-03-01 21:51:56 +00004486#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004487 name = tmpnam_r(buffer);
4488#else
4489 name = tmpnam(buffer);
4490#endif
4491 if (name == NULL) {
4492 PyErr_SetObject(PyExc_OSError,
4493 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004494#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004495 "unexpected NULL from tmpnam_r"
4496#else
4497 "unexpected NULL from tmpnam"
4498#endif
4499 ));
4500 return NULL;
4501 }
4502 return PyString_FromString(buffer);
4503}
4504#endif
4505
4506
Fred Drakec9680921999-12-13 16:37:25 +00004507/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4508 * It maps strings representing configuration variable names to
4509 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004510 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004511 * rarely-used constants. There are three separate tables that use
4512 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004513 *
4514 * This code is always included, even if none of the interfaces that
4515 * need it are included. The #if hackery needed to avoid it would be
4516 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004517 */
4518struct constdef {
4519 char *name;
4520 long value;
4521};
4522
Fred Drake12c6e2d1999-12-14 21:25:03 +00004523static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004524conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4525 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004526{
4527 if (PyInt_Check(arg)) {
4528 *valuep = PyInt_AS_LONG(arg);
4529 return 1;
4530 }
4531 if (PyString_Check(arg)) {
4532 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004533 size_t lo = 0;
4534 size_t mid;
4535 size_t hi = tablesize;
4536 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004537 char *confname = PyString_AS_STRING(arg);
4538 while (lo < hi) {
4539 mid = (lo + hi) / 2;
4540 cmp = strcmp(confname, table[mid].name);
4541 if (cmp < 0)
4542 hi = mid;
4543 else if (cmp > 0)
4544 lo = mid + 1;
4545 else {
4546 *valuep = table[mid].value;
4547 return 1;
4548 }
4549 }
4550 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4551 }
4552 else
4553 PyErr_SetString(PyExc_TypeError,
4554 "configuration names must be strings or integers");
4555 return 0;
4556}
4557
4558
4559#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4560static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004561#ifdef _PC_ABI_AIO_XFER_MAX
4562 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4563#endif
4564#ifdef _PC_ABI_ASYNC_IO
4565 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4566#endif
Fred Drakec9680921999-12-13 16:37:25 +00004567#ifdef _PC_ASYNC_IO
4568 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4569#endif
4570#ifdef _PC_CHOWN_RESTRICTED
4571 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4572#endif
4573#ifdef _PC_FILESIZEBITS
4574 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4575#endif
4576#ifdef _PC_LAST
4577 {"PC_LAST", _PC_LAST},
4578#endif
4579#ifdef _PC_LINK_MAX
4580 {"PC_LINK_MAX", _PC_LINK_MAX},
4581#endif
4582#ifdef _PC_MAX_CANON
4583 {"PC_MAX_CANON", _PC_MAX_CANON},
4584#endif
4585#ifdef _PC_MAX_INPUT
4586 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4587#endif
4588#ifdef _PC_NAME_MAX
4589 {"PC_NAME_MAX", _PC_NAME_MAX},
4590#endif
4591#ifdef _PC_NO_TRUNC
4592 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4593#endif
4594#ifdef _PC_PATH_MAX
4595 {"PC_PATH_MAX", _PC_PATH_MAX},
4596#endif
4597#ifdef _PC_PIPE_BUF
4598 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4599#endif
4600#ifdef _PC_PRIO_IO
4601 {"PC_PRIO_IO", _PC_PRIO_IO},
4602#endif
4603#ifdef _PC_SOCK_MAXBUF
4604 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4605#endif
4606#ifdef _PC_SYNC_IO
4607 {"PC_SYNC_IO", _PC_SYNC_IO},
4608#endif
4609#ifdef _PC_VDISABLE
4610 {"PC_VDISABLE", _PC_VDISABLE},
4611#endif
4612};
4613
Fred Drakec9680921999-12-13 16:37:25 +00004614static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004615conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004616{
4617 return conv_confname(arg, valuep, posix_constants_pathconf,
4618 sizeof(posix_constants_pathconf)
4619 / sizeof(struct constdef));
4620}
4621#endif
4622
4623#ifdef HAVE_FPATHCONF
4624static char posix_fpathconf__doc__[] = "\
4625fpathconf(fd, name) -> integer\n\
4626Return the configuration limit name for the file descriptor fd.\n\
4627If there is no limit, return -1.";
4628
4629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004630posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004631{
4632 PyObject *result = NULL;
4633 int name, fd;
4634
Fred Drake12c6e2d1999-12-14 21:25:03 +00004635 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4636 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004637 long limit;
4638
4639 errno = 0;
4640 limit = fpathconf(fd, name);
4641 if (limit == -1 && errno != 0)
4642 posix_error();
4643 else
4644 result = PyInt_FromLong(limit);
4645 }
4646 return result;
4647}
4648#endif
4649
4650
4651#ifdef HAVE_PATHCONF
4652static char posix_pathconf__doc__[] = "\
4653pathconf(path, name) -> integer\n\
4654Return the configuration limit name for the file or directory path.\n\
4655If there is no limit, return -1.";
4656
4657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004658posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004659{
4660 PyObject *result = NULL;
4661 int name;
4662 char *path;
4663
4664 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4665 conv_path_confname, &name)) {
4666 long limit;
4667
4668 errno = 0;
4669 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004670 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004671 if (errno == EINVAL)
4672 /* could be a path or name problem */
4673 posix_error();
4674 else
4675 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004676 }
Fred Drakec9680921999-12-13 16:37:25 +00004677 else
4678 result = PyInt_FromLong(limit);
4679 }
4680 return result;
4681}
4682#endif
4683
4684#ifdef HAVE_CONFSTR
4685static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004686#ifdef _CS_ARCHITECTURE
4687 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4688#endif
4689#ifdef _CS_HOSTNAME
4690 {"CS_HOSTNAME", _CS_HOSTNAME},
4691#endif
4692#ifdef _CS_HW_PROVIDER
4693 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4694#endif
4695#ifdef _CS_HW_SERIAL
4696 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4697#endif
4698#ifdef _CS_INITTAB_NAME
4699 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4700#endif
Fred Drakec9680921999-12-13 16:37:25 +00004701#ifdef _CS_LFS64_CFLAGS
4702 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4703#endif
4704#ifdef _CS_LFS64_LDFLAGS
4705 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4706#endif
4707#ifdef _CS_LFS64_LIBS
4708 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4709#endif
4710#ifdef _CS_LFS64_LINTFLAGS
4711 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4712#endif
4713#ifdef _CS_LFS_CFLAGS
4714 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4715#endif
4716#ifdef _CS_LFS_LDFLAGS
4717 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4718#endif
4719#ifdef _CS_LFS_LIBS
4720 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4721#endif
4722#ifdef _CS_LFS_LINTFLAGS
4723 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4724#endif
Fred Draked86ed291999-12-15 15:34:33 +00004725#ifdef _CS_MACHINE
4726 {"CS_MACHINE", _CS_MACHINE},
4727#endif
Fred Drakec9680921999-12-13 16:37:25 +00004728#ifdef _CS_PATH
4729 {"CS_PATH", _CS_PATH},
4730#endif
Fred Draked86ed291999-12-15 15:34:33 +00004731#ifdef _CS_RELEASE
4732 {"CS_RELEASE", _CS_RELEASE},
4733#endif
4734#ifdef _CS_SRPC_DOMAIN
4735 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4736#endif
4737#ifdef _CS_SYSNAME
4738 {"CS_SYSNAME", _CS_SYSNAME},
4739#endif
4740#ifdef _CS_VERSION
4741 {"CS_VERSION", _CS_VERSION},
4742#endif
Fred Drakec9680921999-12-13 16:37:25 +00004743#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4744 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4745#endif
4746#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4747 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4748#endif
4749#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4750 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4751#endif
4752#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4753 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4754#endif
4755#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4756 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4757#endif
4758#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4759 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4760#endif
4761#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4762 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4763#endif
4764#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4765 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4766#endif
4767#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4768 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4769#endif
4770#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4771 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4772#endif
4773#ifdef _CS_XBS5_LP64_OFF64_LIBS
4774 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4775#endif
4776#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4777 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4778#endif
4779#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4780 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4781#endif
4782#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4783 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4784#endif
4785#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4786 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4787#endif
4788#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4789 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4790#endif
Fred Draked86ed291999-12-15 15:34:33 +00004791#ifdef _MIPS_CS_AVAIL_PROCESSORS
4792 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4793#endif
4794#ifdef _MIPS_CS_BASE
4795 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4796#endif
4797#ifdef _MIPS_CS_HOSTID
4798 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4799#endif
4800#ifdef _MIPS_CS_HW_NAME
4801 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4802#endif
4803#ifdef _MIPS_CS_NUM_PROCESSORS
4804 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4805#endif
4806#ifdef _MIPS_CS_OSREL_MAJ
4807 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4808#endif
4809#ifdef _MIPS_CS_OSREL_MIN
4810 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4811#endif
4812#ifdef _MIPS_CS_OSREL_PATCH
4813 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4814#endif
4815#ifdef _MIPS_CS_OS_NAME
4816 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4817#endif
4818#ifdef _MIPS_CS_OS_PROVIDER
4819 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4820#endif
4821#ifdef _MIPS_CS_PROCESSORS
4822 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4823#endif
4824#ifdef _MIPS_CS_SERIAL
4825 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4826#endif
4827#ifdef _MIPS_CS_VENDOR
4828 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4829#endif
Fred Drakec9680921999-12-13 16:37:25 +00004830};
4831
4832static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004833conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004834{
4835 return conv_confname(arg, valuep, posix_constants_confstr,
4836 sizeof(posix_constants_confstr)
4837 / sizeof(struct constdef));
4838}
4839
4840static char posix_confstr__doc__[] = "\
4841confstr(name) -> string\n\
4842Return a string-valued system configuration variable.";
4843
4844static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004845posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004846{
4847 PyObject *result = NULL;
4848 int name;
4849 char buffer[64];
4850
4851 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4852 int len = confstr(name, buffer, sizeof(buffer));
4853
Fred Drakec9680921999-12-13 16:37:25 +00004854 errno = 0;
4855 if (len == 0) {
4856 if (errno != 0)
4857 posix_error();
4858 else
4859 result = PyString_FromString("");
4860 }
4861 else {
4862 if (len >= sizeof(buffer)) {
4863 result = PyString_FromStringAndSize(NULL, len);
4864 if (result != NULL)
4865 confstr(name, PyString_AS_STRING(result), len+1);
4866 }
4867 else
4868 result = PyString_FromString(buffer);
4869 }
4870 }
4871 return result;
4872}
4873#endif
4874
4875
4876#ifdef HAVE_SYSCONF
4877static struct constdef posix_constants_sysconf[] = {
4878#ifdef _SC_2_CHAR_TERM
4879 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4880#endif
4881#ifdef _SC_2_C_BIND
4882 {"SC_2_C_BIND", _SC_2_C_BIND},
4883#endif
4884#ifdef _SC_2_C_DEV
4885 {"SC_2_C_DEV", _SC_2_C_DEV},
4886#endif
4887#ifdef _SC_2_C_VERSION
4888 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4889#endif
4890#ifdef _SC_2_FORT_DEV
4891 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4892#endif
4893#ifdef _SC_2_FORT_RUN
4894 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4895#endif
4896#ifdef _SC_2_LOCALEDEF
4897 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4898#endif
4899#ifdef _SC_2_SW_DEV
4900 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4901#endif
4902#ifdef _SC_2_UPE
4903 {"SC_2_UPE", _SC_2_UPE},
4904#endif
4905#ifdef _SC_2_VERSION
4906 {"SC_2_VERSION", _SC_2_VERSION},
4907#endif
Fred Draked86ed291999-12-15 15:34:33 +00004908#ifdef _SC_ABI_ASYNCHRONOUS_IO
4909 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4910#endif
4911#ifdef _SC_ACL
4912 {"SC_ACL", _SC_ACL},
4913#endif
Fred Drakec9680921999-12-13 16:37:25 +00004914#ifdef _SC_AIO_LISTIO_MAX
4915 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4916#endif
Fred Drakec9680921999-12-13 16:37:25 +00004917#ifdef _SC_AIO_MAX
4918 {"SC_AIO_MAX", _SC_AIO_MAX},
4919#endif
4920#ifdef _SC_AIO_PRIO_DELTA_MAX
4921 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4922#endif
4923#ifdef _SC_ARG_MAX
4924 {"SC_ARG_MAX", _SC_ARG_MAX},
4925#endif
4926#ifdef _SC_ASYNCHRONOUS_IO
4927 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4928#endif
4929#ifdef _SC_ATEXIT_MAX
4930 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4931#endif
Fred Draked86ed291999-12-15 15:34:33 +00004932#ifdef _SC_AUDIT
4933 {"SC_AUDIT", _SC_AUDIT},
4934#endif
Fred Drakec9680921999-12-13 16:37:25 +00004935#ifdef _SC_AVPHYS_PAGES
4936 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4937#endif
4938#ifdef _SC_BC_BASE_MAX
4939 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4940#endif
4941#ifdef _SC_BC_DIM_MAX
4942 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4943#endif
4944#ifdef _SC_BC_SCALE_MAX
4945 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4946#endif
4947#ifdef _SC_BC_STRING_MAX
4948 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4949#endif
Fred Draked86ed291999-12-15 15:34:33 +00004950#ifdef _SC_CAP
4951 {"SC_CAP", _SC_CAP},
4952#endif
Fred Drakec9680921999-12-13 16:37:25 +00004953#ifdef _SC_CHARCLASS_NAME_MAX
4954 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4955#endif
4956#ifdef _SC_CHAR_BIT
4957 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4958#endif
4959#ifdef _SC_CHAR_MAX
4960 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4961#endif
4962#ifdef _SC_CHAR_MIN
4963 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4964#endif
4965#ifdef _SC_CHILD_MAX
4966 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4967#endif
4968#ifdef _SC_CLK_TCK
4969 {"SC_CLK_TCK", _SC_CLK_TCK},
4970#endif
4971#ifdef _SC_COHER_BLKSZ
4972 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4973#endif
4974#ifdef _SC_COLL_WEIGHTS_MAX
4975 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4976#endif
4977#ifdef _SC_DCACHE_ASSOC
4978 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4979#endif
4980#ifdef _SC_DCACHE_BLKSZ
4981 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4982#endif
4983#ifdef _SC_DCACHE_LINESZ
4984 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4985#endif
4986#ifdef _SC_DCACHE_SZ
4987 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4988#endif
4989#ifdef _SC_DCACHE_TBLKSZ
4990 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4991#endif
4992#ifdef _SC_DELAYTIMER_MAX
4993 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4994#endif
4995#ifdef _SC_EQUIV_CLASS_MAX
4996 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4997#endif
4998#ifdef _SC_EXPR_NEST_MAX
4999 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5000#endif
5001#ifdef _SC_FSYNC
5002 {"SC_FSYNC", _SC_FSYNC},
5003#endif
5004#ifdef _SC_GETGR_R_SIZE_MAX
5005 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5006#endif
5007#ifdef _SC_GETPW_R_SIZE_MAX
5008 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5009#endif
5010#ifdef _SC_ICACHE_ASSOC
5011 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5012#endif
5013#ifdef _SC_ICACHE_BLKSZ
5014 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5015#endif
5016#ifdef _SC_ICACHE_LINESZ
5017 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5018#endif
5019#ifdef _SC_ICACHE_SZ
5020 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5021#endif
Fred Draked86ed291999-12-15 15:34:33 +00005022#ifdef _SC_INF
5023 {"SC_INF", _SC_INF},
5024#endif
Fred Drakec9680921999-12-13 16:37:25 +00005025#ifdef _SC_INT_MAX
5026 {"SC_INT_MAX", _SC_INT_MAX},
5027#endif
5028#ifdef _SC_INT_MIN
5029 {"SC_INT_MIN", _SC_INT_MIN},
5030#endif
5031#ifdef _SC_IOV_MAX
5032 {"SC_IOV_MAX", _SC_IOV_MAX},
5033#endif
Fred Draked86ed291999-12-15 15:34:33 +00005034#ifdef _SC_IP_SECOPTS
5035 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5036#endif
Fred Drakec9680921999-12-13 16:37:25 +00005037#ifdef _SC_JOB_CONTROL
5038 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5039#endif
Fred Draked86ed291999-12-15 15:34:33 +00005040#ifdef _SC_KERN_POINTERS
5041 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5042#endif
5043#ifdef _SC_KERN_SIM
5044 {"SC_KERN_SIM", _SC_KERN_SIM},
5045#endif
Fred Drakec9680921999-12-13 16:37:25 +00005046#ifdef _SC_LINE_MAX
5047 {"SC_LINE_MAX", _SC_LINE_MAX},
5048#endif
5049#ifdef _SC_LOGIN_NAME_MAX
5050 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5051#endif
5052#ifdef _SC_LOGNAME_MAX
5053 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5054#endif
5055#ifdef _SC_LONG_BIT
5056 {"SC_LONG_BIT", _SC_LONG_BIT},
5057#endif
Fred Draked86ed291999-12-15 15:34:33 +00005058#ifdef _SC_MAC
5059 {"SC_MAC", _SC_MAC},
5060#endif
Fred Drakec9680921999-12-13 16:37:25 +00005061#ifdef _SC_MAPPED_FILES
5062 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5063#endif
5064#ifdef _SC_MAXPID
5065 {"SC_MAXPID", _SC_MAXPID},
5066#endif
5067#ifdef _SC_MB_LEN_MAX
5068 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5069#endif
5070#ifdef _SC_MEMLOCK
5071 {"SC_MEMLOCK", _SC_MEMLOCK},
5072#endif
5073#ifdef _SC_MEMLOCK_RANGE
5074 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5075#endif
5076#ifdef _SC_MEMORY_PROTECTION
5077 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5078#endif
5079#ifdef _SC_MESSAGE_PASSING
5080 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5081#endif
Fred Draked86ed291999-12-15 15:34:33 +00005082#ifdef _SC_MMAP_FIXED_ALIGNMENT
5083 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5084#endif
Fred Drakec9680921999-12-13 16:37:25 +00005085#ifdef _SC_MQ_OPEN_MAX
5086 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5087#endif
5088#ifdef _SC_MQ_PRIO_MAX
5089 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5090#endif
Fred Draked86ed291999-12-15 15:34:33 +00005091#ifdef _SC_NACLS_MAX
5092 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5093#endif
Fred Drakec9680921999-12-13 16:37:25 +00005094#ifdef _SC_NGROUPS_MAX
5095 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5096#endif
5097#ifdef _SC_NL_ARGMAX
5098 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5099#endif
5100#ifdef _SC_NL_LANGMAX
5101 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5102#endif
5103#ifdef _SC_NL_MSGMAX
5104 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5105#endif
5106#ifdef _SC_NL_NMAX
5107 {"SC_NL_NMAX", _SC_NL_NMAX},
5108#endif
5109#ifdef _SC_NL_SETMAX
5110 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5111#endif
5112#ifdef _SC_NL_TEXTMAX
5113 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5114#endif
5115#ifdef _SC_NPROCESSORS_CONF
5116 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5117#endif
5118#ifdef _SC_NPROCESSORS_ONLN
5119 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5120#endif
Fred Draked86ed291999-12-15 15:34:33 +00005121#ifdef _SC_NPROC_CONF
5122 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5123#endif
5124#ifdef _SC_NPROC_ONLN
5125 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5126#endif
Fred Drakec9680921999-12-13 16:37:25 +00005127#ifdef _SC_NZERO
5128 {"SC_NZERO", _SC_NZERO},
5129#endif
5130#ifdef _SC_OPEN_MAX
5131 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5132#endif
5133#ifdef _SC_PAGESIZE
5134 {"SC_PAGESIZE", _SC_PAGESIZE},
5135#endif
5136#ifdef _SC_PAGE_SIZE
5137 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5138#endif
5139#ifdef _SC_PASS_MAX
5140 {"SC_PASS_MAX", _SC_PASS_MAX},
5141#endif
5142#ifdef _SC_PHYS_PAGES
5143 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5144#endif
5145#ifdef _SC_PII
5146 {"SC_PII", _SC_PII},
5147#endif
5148#ifdef _SC_PII_INTERNET
5149 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5150#endif
5151#ifdef _SC_PII_INTERNET_DGRAM
5152 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5153#endif
5154#ifdef _SC_PII_INTERNET_STREAM
5155 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5156#endif
5157#ifdef _SC_PII_OSI
5158 {"SC_PII_OSI", _SC_PII_OSI},
5159#endif
5160#ifdef _SC_PII_OSI_CLTS
5161 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5162#endif
5163#ifdef _SC_PII_OSI_COTS
5164 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5165#endif
5166#ifdef _SC_PII_OSI_M
5167 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5168#endif
5169#ifdef _SC_PII_SOCKET
5170 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5171#endif
5172#ifdef _SC_PII_XTI
5173 {"SC_PII_XTI", _SC_PII_XTI},
5174#endif
5175#ifdef _SC_POLL
5176 {"SC_POLL", _SC_POLL},
5177#endif
5178#ifdef _SC_PRIORITIZED_IO
5179 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5180#endif
5181#ifdef _SC_PRIORITY_SCHEDULING
5182 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5183#endif
5184#ifdef _SC_REALTIME_SIGNALS
5185 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5186#endif
5187#ifdef _SC_RE_DUP_MAX
5188 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5189#endif
5190#ifdef _SC_RTSIG_MAX
5191 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5192#endif
5193#ifdef _SC_SAVED_IDS
5194 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5195#endif
5196#ifdef _SC_SCHAR_MAX
5197 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5198#endif
5199#ifdef _SC_SCHAR_MIN
5200 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5201#endif
5202#ifdef _SC_SELECT
5203 {"SC_SELECT", _SC_SELECT},
5204#endif
5205#ifdef _SC_SEMAPHORES
5206 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5207#endif
5208#ifdef _SC_SEM_NSEMS_MAX
5209 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5210#endif
5211#ifdef _SC_SEM_VALUE_MAX
5212 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5213#endif
5214#ifdef _SC_SHARED_MEMORY_OBJECTS
5215 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5216#endif
5217#ifdef _SC_SHRT_MAX
5218 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5219#endif
5220#ifdef _SC_SHRT_MIN
5221 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5222#endif
5223#ifdef _SC_SIGQUEUE_MAX
5224 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5225#endif
5226#ifdef _SC_SIGRT_MAX
5227 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5228#endif
5229#ifdef _SC_SIGRT_MIN
5230 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5231#endif
Fred Draked86ed291999-12-15 15:34:33 +00005232#ifdef _SC_SOFTPOWER
5233 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5234#endif
Fred Drakec9680921999-12-13 16:37:25 +00005235#ifdef _SC_SPLIT_CACHE
5236 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5237#endif
5238#ifdef _SC_SSIZE_MAX
5239 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5240#endif
5241#ifdef _SC_STACK_PROT
5242 {"SC_STACK_PROT", _SC_STACK_PROT},
5243#endif
5244#ifdef _SC_STREAM_MAX
5245 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5246#endif
5247#ifdef _SC_SYNCHRONIZED_IO
5248 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5249#endif
5250#ifdef _SC_THREADS
5251 {"SC_THREADS", _SC_THREADS},
5252#endif
5253#ifdef _SC_THREAD_ATTR_STACKADDR
5254 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5255#endif
5256#ifdef _SC_THREAD_ATTR_STACKSIZE
5257 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5258#endif
5259#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5260 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5261#endif
5262#ifdef _SC_THREAD_KEYS_MAX
5263 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5264#endif
5265#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5266 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5267#endif
5268#ifdef _SC_THREAD_PRIO_INHERIT
5269 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5270#endif
5271#ifdef _SC_THREAD_PRIO_PROTECT
5272 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5273#endif
5274#ifdef _SC_THREAD_PROCESS_SHARED
5275 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5276#endif
5277#ifdef _SC_THREAD_SAFE_FUNCTIONS
5278 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5279#endif
5280#ifdef _SC_THREAD_STACK_MIN
5281 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5282#endif
5283#ifdef _SC_THREAD_THREADS_MAX
5284 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5285#endif
5286#ifdef _SC_TIMERS
5287 {"SC_TIMERS", _SC_TIMERS},
5288#endif
5289#ifdef _SC_TIMER_MAX
5290 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5291#endif
5292#ifdef _SC_TTY_NAME_MAX
5293 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5294#endif
5295#ifdef _SC_TZNAME_MAX
5296 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5297#endif
5298#ifdef _SC_T_IOV_MAX
5299 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5300#endif
5301#ifdef _SC_UCHAR_MAX
5302 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5303#endif
5304#ifdef _SC_UINT_MAX
5305 {"SC_UINT_MAX", _SC_UINT_MAX},
5306#endif
5307#ifdef _SC_UIO_MAXIOV
5308 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5309#endif
5310#ifdef _SC_ULONG_MAX
5311 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5312#endif
5313#ifdef _SC_USHRT_MAX
5314 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5315#endif
5316#ifdef _SC_VERSION
5317 {"SC_VERSION", _SC_VERSION},
5318#endif
5319#ifdef _SC_WORD_BIT
5320 {"SC_WORD_BIT", _SC_WORD_BIT},
5321#endif
5322#ifdef _SC_XBS5_ILP32_OFF32
5323 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5324#endif
5325#ifdef _SC_XBS5_ILP32_OFFBIG
5326 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5327#endif
5328#ifdef _SC_XBS5_LP64_OFF64
5329 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5330#endif
5331#ifdef _SC_XBS5_LPBIG_OFFBIG
5332 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5333#endif
5334#ifdef _SC_XOPEN_CRYPT
5335 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5336#endif
5337#ifdef _SC_XOPEN_ENH_I18N
5338 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5339#endif
5340#ifdef _SC_XOPEN_LEGACY
5341 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5342#endif
5343#ifdef _SC_XOPEN_REALTIME
5344 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5345#endif
5346#ifdef _SC_XOPEN_REALTIME_THREADS
5347 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5348#endif
5349#ifdef _SC_XOPEN_SHM
5350 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5351#endif
5352#ifdef _SC_XOPEN_UNIX
5353 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5354#endif
5355#ifdef _SC_XOPEN_VERSION
5356 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5357#endif
5358#ifdef _SC_XOPEN_XCU_VERSION
5359 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5360#endif
5361#ifdef _SC_XOPEN_XPG2
5362 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5363#endif
5364#ifdef _SC_XOPEN_XPG3
5365 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5366#endif
5367#ifdef _SC_XOPEN_XPG4
5368 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5369#endif
5370};
5371
5372static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005373conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005374{
5375 return conv_confname(arg, valuep, posix_constants_sysconf,
5376 sizeof(posix_constants_sysconf)
5377 / sizeof(struct constdef));
5378}
5379
5380static char posix_sysconf__doc__[] = "\
5381sysconf(name) -> integer\n\
5382Return an integer-valued system configuration variable.";
5383
5384static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005385posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005386{
5387 PyObject *result = NULL;
5388 int name;
5389
5390 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5391 int value;
5392
5393 errno = 0;
5394 value = sysconf(name);
5395 if (value == -1 && errno != 0)
5396 posix_error();
5397 else
5398 result = PyInt_FromLong(value);
5399 }
5400 return result;
5401}
5402#endif
5403
5404
Fred Drakebec628d1999-12-15 18:31:10 +00005405/* This code is used to ensure that the tables of configuration value names
5406 * are in sorted order as required by conv_confname(), and also to build the
5407 * the exported dictionaries that are used to publish information about the
5408 * names available on the host platform.
5409 *
5410 * Sorting the table at runtime ensures that the table is properly ordered
5411 * when used, even for platforms we're not able to test on. It also makes
5412 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005413 */
Fred Drakebec628d1999-12-15 18:31:10 +00005414
5415static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005416cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005417{
5418 const struct constdef *c1 =
5419 (const struct constdef *) v1;
5420 const struct constdef *c2 =
5421 (const struct constdef *) v2;
5422
5423 return strcmp(c1->name, c2->name);
5424}
5425
5426static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005427setup_confname_table(struct constdef *table, size_t tablesize,
5428 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005429{
Fred Drakebec628d1999-12-15 18:31:10 +00005430 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005431 size_t i;
5432 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005433
5434 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5435 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005436 if (d == NULL)
5437 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005438
Barry Warsaw3155db32000-04-13 15:20:40 +00005439 for (i=0; i < tablesize; ++i) {
5440 PyObject *o = PyInt_FromLong(table[i].value);
5441 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5442 Py_XDECREF(o);
5443 Py_DECREF(d);
5444 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005445 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005446 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005447 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005448 status = PyDict_SetItemString(moddict, tablename, d);
5449 Py_DECREF(d);
5450 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005451}
5452
Fred Drakebec628d1999-12-15 18:31:10 +00005453/* Return -1 on failure, 0 on success. */
5454static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005455setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005456{
5457#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005458 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005459 sizeof(posix_constants_pathconf)
5460 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005461 "pathconf_names", moddict))
5462 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005463#endif
5464#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005465 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005466 sizeof(posix_constants_confstr)
5467 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005468 "confstr_names", moddict))
5469 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005470#endif
5471#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005472 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005473 sizeof(posix_constants_sysconf)
5474 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005475 "sysconf_names", moddict))
5476 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005477#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005478 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005479}
Fred Draked86ed291999-12-15 15:34:33 +00005480
5481
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005482static char posix_abort__doc__[] = "\
5483abort() -> does not return!\n\
5484Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5485in the hardest way possible on the hosting operating system.";
5486
5487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005488posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005489{
5490 if (!PyArg_ParseTuple(args, ":abort"))
5491 return NULL;
5492 abort();
5493 /*NOTREACHED*/
5494 Py_FatalError("abort() called from Python code didn't abort!");
5495 return NULL;
5496}
Fred Drakebec628d1999-12-15 18:31:10 +00005497
Tim Petersf58a7aa2000-09-22 10:05:54 +00005498#ifdef MS_WIN32
5499static char win32_startfile__doc__[] = "\
5500startfile(filepath) - Start a file with its associated application.\n\
5501\n\
5502This acts like double-clicking the file in Explorer, or giving the file\n\
5503name as an argument to the DOS \"start\" command: the file is opened\n\
5504with whatever application (if any) its extension is associated.\n\
5505\n\
5506startfile returns as soon as the associated application is launched.\n\
5507There is no option to wait for the application to close, and no way\n\
5508to retrieve the application's exit status.\n\
5509\n\
5510The filepath is relative to the current directory. If you want to use\n\
5511an absolute path, make sure the first character is not a slash (\"/\");\n\
5512the underlying Win32 ShellExecute function doesn't work if it is.";
5513
5514static PyObject *
5515win32_startfile(PyObject *self, PyObject *args)
5516{
5517 char *filepath;
5518 HINSTANCE rc;
5519 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5520 return NULL;
5521 Py_BEGIN_ALLOW_THREADS
5522 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5523 Py_END_ALLOW_THREADS
5524 if (rc <= (HINSTANCE)32)
5525 return win32_error("startfile", filepath);
5526 Py_INCREF(Py_None);
5527 return Py_None;
5528}
5529#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005530
5531static PyMethodDef posix_methods[] = {
5532 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5533#ifdef HAVE_TTYNAME
5534 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5535#endif
5536 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5537 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005538#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005539 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005540#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005541#ifdef HAVE_CHROOT
5542 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5543#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005544#ifdef HAVE_CTERMID
5545 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5546#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005547#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005548 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005549#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005550#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005551 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005552#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005553 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5554 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5555 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005556#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005557 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005558#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005559#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005560 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005561#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005562 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5563 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5564 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005565#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005566 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005567#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005568#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005569 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005570#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005571 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005572#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005573 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005574#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005575 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5576 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5577 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005578#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005579 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005580#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005581 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005582#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005583 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5584 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005585#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005586#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005587 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5588 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005589#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005590#ifdef HAVE_FORK1
5591 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5592#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005593#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005594 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005595#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005596#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005597 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005598#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005599#ifdef HAVE_FORKPTY
5600 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5601#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005602#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005603 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005604#endif /* HAVE_GETEGID */
5605#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005606 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005607#endif /* HAVE_GETEUID */
5608#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005609 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005610#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005611#ifdef HAVE_GETGROUPS
5612 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5613#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005614 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005615#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005616 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005617#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005618#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005619 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005620#endif /* HAVE_GETPPID */
5621#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005622 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005623#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005624#ifdef HAVE_GETLOGIN
5625 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5626#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005627#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005628 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005629#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005630#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005631 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005632#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005633#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005634 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005635#ifdef MS_WIN32
5636 {"popen2", win32_popen2, METH_VARARGS},
5637 {"popen3", win32_popen3, METH_VARARGS},
5638 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005639 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005640#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005641#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005642#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005643 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005644#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005645#ifdef HAVE_SETEUID
5646 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5647#endif /* HAVE_SETEUID */
5648#ifdef HAVE_SETEGID
5649 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5650#endif /* HAVE_SETEGID */
5651#ifdef HAVE_SETREUID
5652 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5653#endif /* HAVE_SETREUID */
5654#ifdef HAVE_SETREGID
5655 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5656#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005657#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005658 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005659#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005660#ifdef HAVE_SETGROUPS
5661 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5662#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005663#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005664 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005665#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005666#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005667 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005668#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005669#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005670 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005671#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005672#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005673 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005674#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005675#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005676 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005677#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005678#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005679 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005680#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005681#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005682 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005683#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005684 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5685 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5686 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5687 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5688 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5689 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5690 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5691 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5692 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005693 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005694#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005695 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005696#endif
5697#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005698 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005699#endif
5700#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005701 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005702#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005703#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005704 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005705#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005706#ifdef HAVE_UNSETENV
5707 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
5708#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005709#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005710 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005711#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005712#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005713 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005714#endif
5715#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005716 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005717#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005718#ifdef HAVE_SYS_WAIT_H
5719#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005720 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005721#endif /* WIFSTOPPED */
5722#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005723 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005724#endif /* WIFSIGNALED */
5725#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005726 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005727#endif /* WIFEXITED */
5728#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005729 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005730#endif /* WEXITSTATUS */
5731#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005732 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005733#endif /* WTERMSIG */
5734#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005735 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005736#endif /* WSTOPSIG */
5737#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005738#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005739 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005740#endif
5741#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005742 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005743#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005744#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005745 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5746#endif
5747#ifdef HAVE_TEMPNAM
5748 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5749#endif
5750#ifdef HAVE_TMPNAM
5751 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5752#endif
Fred Drakec9680921999-12-13 16:37:25 +00005753#ifdef HAVE_CONFSTR
5754 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5755#endif
5756#ifdef HAVE_SYSCONF
5757 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5758#endif
5759#ifdef HAVE_FPATHCONF
5760 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5761#endif
5762#ifdef HAVE_PATHCONF
5763 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5764#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005765 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005766#ifdef MS_WIN32
5767 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5768#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005769 {NULL, NULL} /* Sentinel */
5770};
5771
5772
Barry Warsaw4a342091996-12-19 23:50:02 +00005773static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005774ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005775{
5776 PyObject* v = PyInt_FromLong(value);
5777 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5778 return -1; /* triggers fatal error */
5779
5780 Py_DECREF(v);
5781 return 0;
5782}
5783
Guido van Rossumd48f2521997-12-05 22:19:34 +00005784#if defined(PYOS_OS2)
5785/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5786static int insertvalues(PyObject *d)
5787{
5788 APIRET rc;
5789 ULONG values[QSV_MAX+1];
5790 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00005791 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00005792
5793 Py_BEGIN_ALLOW_THREADS
5794 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5795 Py_END_ALLOW_THREADS
5796
5797 if (rc != NO_ERROR) {
5798 os2_error(rc);
5799 return -1;
5800 }
5801
5802 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5803 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5804 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5805 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5806 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5807 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5808 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5809
5810 switch (values[QSV_VERSION_MINOR]) {
5811 case 0: ver = "2.00"; break;
5812 case 10: ver = "2.10"; break;
5813 case 11: ver = "2.11"; break;
5814 case 30: ver = "3.00"; break;
5815 case 40: ver = "4.00"; break;
5816 case 50: ver = "5.00"; break;
5817 default:
Tim Peters885d4572001-11-28 20:27:42 +00005818 PyOS_snprintf(tmp, sizeof(tmp),
5819 "%d-%d", values[QSV_VERSION_MAJOR],
5820 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005821 ver = &tmp[0];
5822 }
5823
5824 /* Add Indicator of the Version of the Operating System */
5825 v = PyString_FromString(ver);
5826 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5827 return -1;
5828 Py_DECREF(v);
5829
5830 /* Add Indicator of Which Drive was Used to Boot the System */
5831 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5832 tmp[1] = ':';
5833 tmp[2] = '\0';
5834
5835 v = PyString_FromString(tmp);
5836 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5837 return -1;
5838 Py_DECREF(v);
5839
5840 return 0;
5841}
5842#endif
5843
Barry Warsaw4a342091996-12-19 23:50:02 +00005844static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005845all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005846{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005847#ifdef F_OK
5848 if (ins(d, "F_OK", (long)F_OK)) return -1;
5849#endif
5850#ifdef R_OK
5851 if (ins(d, "R_OK", (long)R_OK)) return -1;
5852#endif
5853#ifdef W_OK
5854 if (ins(d, "W_OK", (long)W_OK)) return -1;
5855#endif
5856#ifdef X_OK
5857 if (ins(d, "X_OK", (long)X_OK)) return -1;
5858#endif
Fred Drakec9680921999-12-13 16:37:25 +00005859#ifdef NGROUPS_MAX
5860 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5861#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005862#ifdef TMP_MAX
5863 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5864#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005865#ifdef WNOHANG
5866 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5867#endif
5868#ifdef O_RDONLY
5869 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5870#endif
5871#ifdef O_WRONLY
5872 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5873#endif
5874#ifdef O_RDWR
5875 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5876#endif
5877#ifdef O_NDELAY
5878 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5879#endif
5880#ifdef O_NONBLOCK
5881 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5882#endif
5883#ifdef O_APPEND
5884 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5885#endif
5886#ifdef O_DSYNC
5887 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5888#endif
5889#ifdef O_RSYNC
5890 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5891#endif
5892#ifdef O_SYNC
5893 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5894#endif
5895#ifdef O_NOCTTY
5896 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5897#endif
5898#ifdef O_CREAT
5899 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5900#endif
5901#ifdef O_EXCL
5902 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5903#endif
5904#ifdef O_TRUNC
5905 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5906#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005907#ifdef O_BINARY
5908 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5909#endif
5910#ifdef O_TEXT
5911 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5912#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005913#ifdef O_LARGEFILE
5914 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
5915#endif
5916
5917/* GNU extensions. */
5918#ifdef O_DIRECT
5919 /* Direct disk access. */
5920 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
5921#endif
5922#ifdef O_DIRECTORY
5923 /* Must be a directory. */
5924 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
5925#endif
5926#ifdef O_NOFOLLOW
5927 /* Do not follow links. */
5928 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
5929#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005930
Guido van Rossum246bc171999-02-01 23:54:31 +00005931#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005932 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5933 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5934 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5935 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5936 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005937#endif
5938
Guido van Rossumd48f2521997-12-05 22:19:34 +00005939#if defined(PYOS_OS2)
5940 if (insertvalues(d)) return -1;
5941#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005942 return 0;
5943}
5944
5945
Tim Peters58e0a8c2001-05-14 22:32:33 +00005946#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005947#define INITFUNC initnt
5948#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005949
5950#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005951#define INITFUNC initos2
5952#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005953
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005954#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005955#define INITFUNC initposix
5956#define MODNAME "posix"
5957#endif
5958
Guido van Rossum3886bb61998-12-04 18:50:17 +00005959DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005960INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005961{
Barry Warsaw53699e91996-12-10 23:23:01 +00005962 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005963
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005964 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005965 posix_methods,
5966 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005967 (PyObject *)NULL,
5968 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005969 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005970
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005971 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005972 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005973 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005974 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005975 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005976
Barry Warsaw4a342091996-12-19 23:50:02 +00005977 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005978 return;
5979
Fred Drakebec628d1999-12-15 18:31:10 +00005980 if (setup_confname_tables(d))
5981 return;
5982
Barry Warsawca74da41999-02-09 19:31:45 +00005983 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005984
Guido van Rossumb3d39562000-01-31 18:41:26 +00005985#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005986 if (posix_putenv_garbage == NULL)
5987 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005988#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005989
5990 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
5991 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
5992
5993 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
5994 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005995}