blob: 1290977350701397200ea7767860d9ce6e5d32ba [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 Peters1ceb5fb2001-11-28 20:32:57 +0000435 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000436 "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;
Tim Peters500bd032001-12-19 19:05:01 +0000682 char *path = NULL; /* pass this to stat; do not free() it */
683 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000684 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000685
686#ifdef MS_WIN32
Tim Peters500bd032001-12-19 19:05:01 +0000687 int pathlen;
688 char pathcopy[MAX_PATH];
Guido van Rossumace88ae2000-04-21 18:54:45 +0000689#endif /* MS_WIN32 */
690
Mark Hammondef8b6542001-05-13 08:04:26 +0000691 if (!PyArg_ParseTuple(args, format,
692 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000693 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000694 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000695
696#ifdef MS_WIN32
697 pathlen = strlen(path);
698 /* the library call can blow up if the file name is too long! */
699 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000700 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000701 errno = ENAMETOOLONG;
702 return posix_error();
703 }
704
Tim Peters500bd032001-12-19 19:05:01 +0000705 /* Remove trailing slash or backslash, unless it's the current
706 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
707 */
708 if (pathlen > 0 &&
709 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
710 /* It does end with a slash -- exempt the root drive cases. */
711 /* XXX UNC root drives should also be exempted? */
712 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
713 /* leave it alone */;
714 else {
715 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000716 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000717 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000718 path = pathcopy;
719 }
720 }
721#endif /* MS_WIN32 */
722
Barry Warsaw53699e91996-12-10 23:23:01 +0000723 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000724 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000725 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000726 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000727 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000728
Tim Peters500bd032001-12-19 19:05:01 +0000729 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000730 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000731}
732
733
734/* POSIX methods */
735
Guido van Rossum94f6f721999-01-06 18:42:14 +0000736static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000737"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000738Test for access to a file.";
739
740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000741posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000742{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000743 char *path;
744 int mode;
745 int res;
746
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000747 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000748 return NULL;
749 Py_BEGIN_ALLOW_THREADS
750 res = access(path, mode);
751 Py_END_ALLOW_THREADS
752 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000753}
754
Guido van Rossumd371ff11999-01-25 16:12:23 +0000755#ifndef F_OK
756#define F_OK 0
757#endif
758#ifndef R_OK
759#define R_OK 4
760#endif
761#ifndef W_OK
762#define W_OK 2
763#endif
764#ifndef X_OK
765#define X_OK 1
766#endif
767
768#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000769static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000770"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000771Return the name of the terminal device connected to 'fd'.";
772
773static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000774posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000775{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000776 int id;
777 char *ret;
778
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000779 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000780 return NULL;
781
Guido van Rossum94f6f721999-01-06 18:42:14 +0000782 ret = ttyname(id);
783 if (ret == NULL)
784 return(posix_error());
785 return(PyString_FromString(ret));
786}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000787#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000788
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000789#ifdef HAVE_CTERMID
790static char posix_ctermid__doc__[] =
791"ctermid() -> String\n\
792Return the name of the controlling terminal for this process.";
793
794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000795posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000796{
797 char *ret;
798 char buffer[L_ctermid];
799
800 if (!PyArg_ParseTuple(args, ":ctermid"))
801 return NULL;
802
Greg Wardb48bc172000-03-01 21:51:56 +0000803#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000804 ret = ctermid_r(buffer);
805#else
806 ret = ctermid(buffer);
807#endif
808 if (ret == NULL)
809 return(posix_error());
810 return(PyString_FromString(buffer));
811}
812#endif
813
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000814static char posix_chdir__doc__[] =
815"chdir(path) -> None\n\
816Change the current working directory to the specified path.";
817
Barry Warsaw53699e91996-12-10 23:23:01 +0000818static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000819posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000820{
Mark Hammondef8b6542001-05-13 08:04:26 +0000821 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000822}
823
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000824
825static char posix_chmod__doc__[] =
826"chmod(path, mode) -> None\n\
827Change the access permissions of a file.";
828
Barry Warsaw53699e91996-12-10 23:23:01 +0000829static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000830posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000831{
Mark Hammondef8b6542001-05-13 08:04:26 +0000832 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000833 int i;
834 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000835 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
836 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000837 return NULL;
838 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000839 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000840 Py_END_ALLOW_THREADS
841 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000842 return posix_error_with_allocated_filename(path);
843 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000844 Py_INCREF(Py_None);
845 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000846}
847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000848
Martin v. Löwis244edc82001-10-04 22:44:26 +0000849#ifdef HAVE_CHROOT
850static char posix_chroot__doc__[] =
851"chroot(path) -> None\n\
852Change root directory to path.";
853
854static PyObject *
855posix_chroot(PyObject *self, PyObject *args)
856{
857 return posix_1str(args, "et:chroot", chroot);
858}
859#endif
860
Guido van Rossum21142a01999-01-08 21:05:37 +0000861#ifdef HAVE_FSYNC
862static char posix_fsync__doc__[] =
863"fsync(fildes) -> None\n\
864force write of file with filedescriptor to disk.";
865
866static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000867posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000868{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000869 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000870}
871#endif /* HAVE_FSYNC */
872
873#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000874
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000875#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000876extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
877#endif
878
Guido van Rossum21142a01999-01-08 21:05:37 +0000879static char posix_fdatasync__doc__[] =
880"fdatasync(fildes) -> None\n\
881force write of file with filedescriptor to disk.\n\
882 does not force update of metadata.";
883
884static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000885posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000886{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000887 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000888}
889#endif /* HAVE_FDATASYNC */
890
891
Fredrik Lundh10723342000-07-10 16:38:09 +0000892#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000893static char posix_chown__doc__[] =
894"chown(path, uid, gid) -> None\n\
895Change the owner and group id of path to the numeric uid and gid.";
896
Barry Warsaw53699e91996-12-10 23:23:01 +0000897static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000898posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000899{
Mark Hammondef8b6542001-05-13 08:04:26 +0000900 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000901 int uid, gid;
902 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000903 if (!PyArg_ParseTuple(args, "etii:chown",
904 Py_FileSystemDefaultEncoding, &path,
905 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000906 return NULL;
907 Py_BEGIN_ALLOW_THREADS
908 res = chown(path, (uid_t) uid, (gid_t) gid);
909 Py_END_ALLOW_THREADS
910 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000911 return posix_error_with_allocated_filename(path);
912 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000913 Py_INCREF(Py_None);
914 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000915}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000916#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000917
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000918
Guido van Rossum36bc6801995-06-14 22:54:23 +0000919#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000920static char posix_getcwd__doc__[] =
921"getcwd() -> path\n\
922Return a string representing the current working directory.";
923
Barry Warsaw53699e91996-12-10 23:23:01 +0000924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000925posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000926{
927 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000928 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000929 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000931 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000932 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000933 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000934 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000935 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000936 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000937}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000938#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000940
Guido van Rossumb6775db1994-08-01 11:34:53 +0000941#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000942static char posix_link__doc__[] =
943"link(src, dst) -> None\n\
944Create a hard link to a file.";
945
Barry Warsaw53699e91996-12-10 23:23:01 +0000946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000947posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000948{
Mark Hammondef8b6542001-05-13 08:04:26 +0000949 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000950}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000951#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000952
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000953
954static char posix_listdir__doc__[] =
955"listdir(path) -> list_of_strings\n\
956Return a list containing the names of the entries in the directory.\n\
957\n\
958 path: path of directory to list\n\
959\n\
960The list is in arbitrary order. It does not include the special\n\
961entries '.' and '..' even if they are present in the directory.";
962
Barry Warsaw53699e91996-12-10 23:23:01 +0000963static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000964posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000965{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000966 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000967 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000968#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000969
Barry Warsaw53699e91996-12-10 23:23:01 +0000970 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000971 HANDLE hFindFile;
972 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000973 /* MAX_PATH characters could mean a bigger encoded string */
974 char namebuf[MAX_PATH*2+5];
975 char *bufptr = namebuf;
976 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000977 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000978
Mark Hammondef8b6542001-05-13 08:04:26 +0000979 if (!PyArg_ParseTuple(args, "et#:listdir",
980 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000981 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000982 ch = namebuf[len-1];
983 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000984 namebuf[len++] = '/';
985 strcpy(namebuf + len, "*.*");
986
Barry Warsaw53699e91996-12-10 23:23:01 +0000987 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000988 return NULL;
989
990 hFindFile = FindFirstFile(namebuf, &FileData);
991 if (hFindFile == INVALID_HANDLE_VALUE) {
992 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000993 if (errno == ERROR_FILE_NOT_FOUND)
994 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000995 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000996 }
997 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000998 if (FileData.cFileName[0] == '.' &&
999 (FileData.cFileName[1] == '\0' ||
1000 FileData.cFileName[1] == '.' &&
1001 FileData.cFileName[2] == '\0'))
1002 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001003 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001004 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001005 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 if (PyList_Append(d, v) != 0) {
1010 Py_DECREF(v);
1011 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001012 d = NULL;
1013 break;
1014 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001015 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001016 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1017
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001018 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001019 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001020
1021 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001022
Tim Peters0bb44a42000-09-15 07:44:49 +00001023#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001024
1025#ifndef MAX_PATH
1026#define MAX_PATH 250
1027#endif
1028 char *name, *pt;
1029 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001030 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001031 char namebuf[MAX_PATH+5];
1032 struct _find_t ep;
1033
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001034 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001035 return NULL;
1036 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001037 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001038 return NULL;
1039 }
1040 strcpy(namebuf, name);
1041 for (pt = namebuf; *pt; pt++)
1042 if (*pt == '/')
1043 *pt = '\\';
1044 if (namebuf[len-1] != '\\')
1045 namebuf[len++] = '\\';
1046 strcpy(namebuf + len, "*.*");
1047
Barry Warsaw53699e91996-12-10 23:23:01 +00001048 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001049 return NULL;
1050
1051 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001052 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1053 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001054 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001055 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001056 }
1057 do {
1058 if (ep.name[0] == '.' &&
1059 (ep.name[1] == '\0' ||
1060 ep.name[1] == '.' &&
1061 ep.name[2] == '\0'))
1062 continue;
1063 strcpy(namebuf, ep.name);
1064 for (pt = namebuf; *pt; pt++)
1065 if (isupper(*pt))
1066 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001067 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001068 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001069 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 if (PyList_Append(d, v) != 0) {
1074 Py_DECREF(v);
1075 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001076 d = NULL;
1077 break;
1078 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001079 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001080 } while (_dos_findnext(&ep) == 0);
1081
1082 return d;
1083
Tim Peters0bb44a42000-09-15 07:44:49 +00001084#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001085
1086#ifndef MAX_PATH
1087#define MAX_PATH CCHMAXPATH
1088#endif
1089 char *name, *pt;
1090 int len;
1091 PyObject *d, *v;
1092 char namebuf[MAX_PATH+5];
1093 HDIR hdir = 1;
1094 ULONG srchcnt = 1;
1095 FILEFINDBUF3 ep;
1096 APIRET rc;
1097
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001098 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001099 return NULL;
1100 if (len >= MAX_PATH) {
1101 PyErr_SetString(PyExc_ValueError, "path too long");
1102 return NULL;
1103 }
1104 strcpy(namebuf, name);
1105 for (pt = namebuf; *pt; pt++)
1106 if (*pt == '/')
1107 *pt = '\\';
1108 if (namebuf[len-1] != '\\')
1109 namebuf[len++] = '\\';
1110 strcpy(namebuf + len, "*.*");
1111
1112 if ((d = PyList_New(0)) == NULL)
1113 return NULL;
1114
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001115 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1116 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001117 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001118 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1119 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1120 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001121
1122 if (rc != NO_ERROR) {
1123 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001124 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001125 }
1126
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001127 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001128 do {
1129 if (ep.achName[0] == '.'
1130 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001131 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001132
1133 strcpy(namebuf, ep.achName);
1134
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001135 /* Leave Case of Name Alone -- In Native Form */
1136 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001137
1138 v = PyString_FromString(namebuf);
1139 if (v == NULL) {
1140 Py_DECREF(d);
1141 d = NULL;
1142 break;
1143 }
1144 if (PyList_Append(d, v) != 0) {
1145 Py_DECREF(v);
1146 Py_DECREF(d);
1147 d = NULL;
1148 break;
1149 }
1150 Py_DECREF(v);
1151 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1152 }
1153
1154 return d;
1155#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001156
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001157 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001158 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001159 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001160 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001161 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001163 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001164 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001165 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001166 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001167 closedir(dirp);
1168 return NULL;
1169 }
1170 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001171 if (ep->d_name[0] == '.' &&
1172 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001173 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001174 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001175 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001176 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001177 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 if (PyList_Append(d, v) != 0) {
1182 Py_DECREF(v);
1183 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184 d = NULL;
1185 break;
1186 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001187 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001188 }
1189 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001190
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001192
Tim Peters0bb44a42000-09-15 07:44:49 +00001193#endif /* which OS */
1194} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001195
Mark Hammondef8b6542001-05-13 08:04:26 +00001196#ifdef MS_WIN32
1197/* A helper function for abspath on win32 */
1198static PyObject *
1199posix__getfullpathname(PyObject *self, PyObject *args)
1200{
1201 /* assume encoded strings wont more than double no of chars */
1202 char inbuf[MAX_PATH*2];
1203 char *inbufp = inbuf;
1204 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1205 char outbuf[MAX_PATH*2];
1206 char *temp;
1207 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1208 Py_FileSystemDefaultEncoding, &inbufp,
1209 &insize))
1210 return NULL;
1211 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1212 outbuf, &temp))
1213 return win32_error("GetFullPathName", inbuf);
1214 return PyString_FromString(outbuf);
1215} /* end of posix__getfullpathname */
1216#endif /* MS_WIN32 */
1217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001218static char posix_mkdir__doc__[] =
1219"mkdir(path [, mode=0777]) -> None\n\
1220Create a directory.";
1221
Barry Warsaw53699e91996-12-10 23:23:01 +00001222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001223posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001224{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001225 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001226 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001227 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001228 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1229 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001230 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001231 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001232#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001233 res = mkdir(path);
1234#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001235 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001236#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001237 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001238 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001239 return posix_error_with_allocated_filename(path);
1240 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001241 Py_INCREF(Py_None);
1242 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001243}
1244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001245
Guido van Rossumb6775db1994-08-01 11:34:53 +00001246#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001247#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1248#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1249#include <sys/resource.h>
1250#endif
1251#endif
1252
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001253static char posix_nice__doc__[] =
1254"nice(inc) -> new_priority\n\
1255Decrease the priority of process and return new priority.";
1256
Barry Warsaw53699e91996-12-10 23:23:01 +00001257static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001258posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001259{
1260 int increment, value;
1261
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001262 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001263 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001264
1265 /* There are two flavours of 'nice': one that returns the new
1266 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001267 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1268 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001269
1270 If we are of the nice family that returns the new priority, we
1271 need to clear errno before the call, and check if errno is filled
1272 before calling posix_error() on a returnvalue of -1, because the
1273 -1 may be the actual new priority! */
1274
1275 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001276 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001277#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001278 if (value == 0)
1279 value = getpriority(PRIO_PROCESS, 0);
1280#endif
1281 if (value == -1 && errno != 0)
1282 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001283 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001284 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001285}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001286#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001287
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001288
1289static char posix_rename__doc__[] =
1290"rename(old, new) -> None\n\
1291Rename a file or directory.";
1292
Barry Warsaw53699e91996-12-10 23:23:01 +00001293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001294posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001295{
Mark Hammondef8b6542001-05-13 08:04:26 +00001296 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001297}
1298
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001299
1300static char posix_rmdir__doc__[] =
1301"rmdir(path) -> None\n\
1302Remove a directory.";
1303
Barry Warsaw53699e91996-12-10 23:23:01 +00001304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001305posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306{
Mark Hammondef8b6542001-05-13 08:04:26 +00001307 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308}
1309
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001310
1311static char posix_stat__doc__[] =
1312"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1313Perform a stat system call on the given path.";
1314
Barry Warsaw53699e91996-12-10 23:23:01 +00001315static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001316posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001317{
Mark Hammondef8b6542001-05-13 08:04:26 +00001318 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001319}
1320
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001321
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001322#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001323static char posix_system__doc__[] =
1324"system(command) -> exit_status\n\
1325Execute the command (a string) in a subshell.";
1326
Barry Warsaw53699e91996-12-10 23:23:01 +00001327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001328posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001329{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001330 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001331 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001332 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001334 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001335 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001336 Py_END_ALLOW_THREADS
1337 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001338}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001339#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001341
1342static char posix_umask__doc__[] =
1343"umask(new_mask) -> old_mask\n\
1344Set the current numeric umask and return the previous umask.";
1345
Barry Warsaw53699e91996-12-10 23:23:01 +00001346static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001347posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001348{
1349 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001350 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001351 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001352 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001353 if (i < 0)
1354 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001355 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001356}
1357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001358
1359static char posix_unlink__doc__[] =
1360"unlink(path) -> None\n\
1361Remove a file (same as remove(path)).";
1362
1363static char posix_remove__doc__[] =
1364"remove(path) -> None\n\
1365Remove a file (same as unlink(path)).";
1366
Barry Warsaw53699e91996-12-10 23:23:01 +00001367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001368posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001369{
Mark Hammondef8b6542001-05-13 08:04:26 +00001370 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001371}
1372
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001373
Guido van Rossumb6775db1994-08-01 11:34:53 +00001374#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001375static char posix_uname__doc__[] =
1376"uname() -> (sysname, nodename, release, version, machine)\n\
1377Return a tuple identifying the current operating system.";
1378
Barry Warsaw53699e91996-12-10 23:23:01 +00001379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001380posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001381{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001382 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001383 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001384 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001385 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001386 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001387 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001388 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001389 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001390 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001391 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001392 u.sysname,
1393 u.nodename,
1394 u.release,
1395 u.version,
1396 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001397}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001398#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001400
1401static char posix_utime__doc__[] =
1402"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001403utime(path, None) -> None\n\
1404Set the access and modified time of the file to the given values. If the\n\
1405second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001406
Barry Warsaw53699e91996-12-10 23:23:01 +00001407static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001408posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001409{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001410 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001411 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001412 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001413 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001414
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001415/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001416#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001417 struct utimbuf buf;
1418#define ATIME buf.actime
1419#define MTIME buf.modtime
1420#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001421#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001422 time_t buf[2];
1423#define ATIME buf[0]
1424#define MTIME buf[1]
1425#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001426#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001427
Barry Warsaw3cef8562000-05-01 16:17:24 +00001428 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001429 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001430 if (arg == Py_None) {
1431 /* optional time values not given */
1432 Py_BEGIN_ALLOW_THREADS
1433 res = utime(path, NULL);
1434 Py_END_ALLOW_THREADS
1435 }
1436 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1437 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001438 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001439 return NULL;
1440 }
1441 else {
1442 ATIME = atime;
1443 MTIME = mtime;
1444 Py_BEGIN_ALLOW_THREADS
1445 res = utime(path, UTIME_ARG);
1446 Py_END_ALLOW_THREADS
1447 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001448 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001449 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001450 Py_INCREF(Py_None);
1451 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001452#undef UTIME_ARG
1453#undef ATIME
1454#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001455}
1456
Guido van Rossum85e3b011991-06-03 12:42:10 +00001457
Guido van Rossum3b066191991-06-04 19:40:25 +00001458/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001460static char posix__exit__doc__[] =
1461"_exit(status)\n\
1462Exit to the system with specified status, without normal exit processing.";
1463
Barry Warsaw53699e91996-12-10 23:23:01 +00001464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001465posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001466{
1467 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001468 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001469 return NULL;
1470 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001471 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001472}
1473
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001474
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001475#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001476static char posix_execv__doc__[] =
1477"execv(path, args)\n\
1478Execute an executable path with arguments, replacing current process.\n\
1479\n\
1480 path: path of executable file\n\
1481 args: tuple or list of strings";
1482
Barry Warsaw53699e91996-12-10 23:23:01 +00001483static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001484posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001485{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001486 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001487 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001488 char **argvlist;
1489 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001490 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001491
Guido van Rossum89b33251993-10-22 14:26:06 +00001492 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001493 argv is a list or tuple of strings. */
1494
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001495 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001496 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001497 if (PyList_Check(argv)) {
1498 argc = PyList_Size(argv);
1499 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001500 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001501 else if (PyTuple_Check(argv)) {
1502 argc = PyTuple_Size(argv);
1503 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001504 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001505 else {
Fred Drake661ea262000-10-24 19:57:45 +00001506 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001507 return NULL;
1508 }
1509
1510 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001511 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001512 return NULL;
1513 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001514
Barry Warsaw53699e91996-12-10 23:23:01 +00001515 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001516 if (argvlist == NULL)
1517 return NULL;
1518 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001519 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1520 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001521 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001522 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001523 return NULL;
1524
Guido van Rossum85e3b011991-06-03 12:42:10 +00001525 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001526 }
1527 argvlist[argc] = NULL;
1528
Guido van Rossumb6775db1994-08-01 11:34:53 +00001529#ifdef BAD_EXEC_PROTOTYPES
1530 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001531#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001532 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001533#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001534
Guido van Rossum85e3b011991-06-03 12:42:10 +00001535 /* If we get here it's definitely an error */
1536
Barry Warsaw53699e91996-12-10 23:23:01 +00001537 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001538 return posix_error();
1539}
1540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001541
1542static char posix_execve__doc__[] =
1543"execve(path, args, env)\n\
1544Execute a path with arguments and environment, replacing current process.\n\
1545\n\
1546 path: path of executable file\n\
1547 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001548 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001549
Barry Warsaw53699e91996-12-10 23:23:01 +00001550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001551posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001552{
1553 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001554 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001555 char **argvlist;
1556 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001557 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001558 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001559 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001560
1561 /* execve has three arguments: (path, argv, env), where
1562 argv is a list or tuple of strings and env is a dictionary
1563 like posix.environ. */
1564
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001565 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001566 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001567 if (PyList_Check(argv)) {
1568 argc = PyList_Size(argv);
1569 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001570 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001571 else if (PyTuple_Check(argv)) {
1572 argc = PyTuple_Size(argv);
1573 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001574 }
1575 else {
Fred Drake661ea262000-10-24 19:57:45 +00001576 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001577 return NULL;
1578 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001579 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001580 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001581 return NULL;
1582 }
1583
Guido van Rossum50422b42000-04-26 20:34:28 +00001584 if (argc == 0) {
1585 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001586 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001587 return NULL;
1588 }
1589
Barry Warsaw53699e91996-12-10 23:23:01 +00001590 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001591 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001592 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001593 return NULL;
1594 }
1595 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001596 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001597 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001598 &argvlist[i]))
1599 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001600 goto fail_1;
1601 }
1602 }
1603 argvlist[argc] = NULL;
1604
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001605 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001606 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001607 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001608 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001609 goto fail_1;
1610 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001611 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001612 keys = PyMapping_Keys(env);
1613 vals = PyMapping_Values(env);
1614 if (!keys || !vals)
1615 goto fail_2;
1616
1617 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001618 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001619 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001620
1621 key = PyList_GetItem(keys, pos);
1622 val = PyList_GetItem(vals, pos);
1623 if (!key || !val)
1624 goto fail_2;
1625
Fred Drake661ea262000-10-24 19:57:45 +00001626 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1627 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001628 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001629 goto fail_2;
1630 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001631
1632#if defined(PYOS_OS2)
1633 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1634 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1635#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001636 len = PyString_Size(key) + PyString_Size(val) + 2;
1637 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001638 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001639 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001640 goto fail_2;
1641 }
Tim Petersc8996f52001-12-03 20:41:00 +00001642 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001643 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001644#if defined(PYOS_OS2)
1645 }
1646#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001647 }
1648 envlist[envc] = 0;
1649
Guido van Rossumb6775db1994-08-01 11:34:53 +00001650
1651#ifdef BAD_EXEC_PROTOTYPES
1652 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001653#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001654 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001655#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001656
1657 /* If we get here it's definitely an error */
1658
1659 (void) posix_error();
1660
1661 fail_2:
1662 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001663 PyMem_DEL(envlist[envc]);
1664 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001665 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001666 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001667 Py_XDECREF(vals);
1668 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001669 return NULL;
1670}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001671#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001673
Guido van Rossuma1065681999-01-25 23:20:23 +00001674#ifdef HAVE_SPAWNV
1675static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001676"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001677Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001678\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001679 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001680 path: path of executable file\n\
1681 args: tuple or list of strings";
1682
1683static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001684posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001685{
1686 char *path;
1687 PyObject *argv;
1688 char **argvlist;
1689 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001690 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001691 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001692
1693 /* spawnv has three arguments: (mode, path, argv), where
1694 argv is a list or tuple of strings. */
1695
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001696 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001697 return NULL;
1698 if (PyList_Check(argv)) {
1699 argc = PyList_Size(argv);
1700 getitem = PyList_GetItem;
1701 }
1702 else if (PyTuple_Check(argv)) {
1703 argc = PyTuple_Size(argv);
1704 getitem = PyTuple_GetItem;
1705 }
1706 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001707 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001708 return NULL;
1709 }
1710
1711 argvlist = PyMem_NEW(char *, argc+1);
1712 if (argvlist == NULL)
1713 return NULL;
1714 for (i = 0; i < argc; i++) {
1715 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1716 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001717 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001718 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001719 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001720 }
1721 }
1722 argvlist[argc] = NULL;
1723
Guido van Rossum246bc171999-02-01 23:54:31 +00001724 if (mode == _OLD_P_OVERLAY)
1725 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001726
1727 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001728 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001729 Py_END_ALLOW_THREADS
1730
Guido van Rossuma1065681999-01-25 23:20:23 +00001731 PyMem_DEL(argvlist);
1732
Fred Drake699f3522000-06-29 21:12:41 +00001733 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001734 return posix_error();
1735 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001736#if SIZEOF_LONG == SIZEOF_VOID_P
1737 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001738#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001739 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001740#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001741}
1742
1743
1744static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001745"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001746Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001747\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001748 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001749 path: path of executable file\n\
1750 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001751 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001752
1753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001754posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001755{
1756 char *path;
1757 PyObject *argv, *env;
1758 char **argvlist;
1759 char **envlist;
1760 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1761 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001762 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001763 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001764
1765 /* spawnve has four arguments: (mode, path, argv, env), where
1766 argv is a list or tuple of strings and env is a dictionary
1767 like posix.environ. */
1768
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001769 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001770 return NULL;
1771 if (PyList_Check(argv)) {
1772 argc = PyList_Size(argv);
1773 getitem = PyList_GetItem;
1774 }
1775 else if (PyTuple_Check(argv)) {
1776 argc = PyTuple_Size(argv);
1777 getitem = PyTuple_GetItem;
1778 }
1779 else {
Fred Drake661ea262000-10-24 19:57:45 +00001780 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001781 return NULL;
1782 }
1783 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001784 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001785 return NULL;
1786 }
1787
1788 argvlist = PyMem_NEW(char *, argc+1);
1789 if (argvlist == NULL) {
1790 PyErr_NoMemory();
1791 return NULL;
1792 }
1793 for (i = 0; i < argc; i++) {
1794 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001795 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001796 &argvlist[i]))
1797 {
1798 goto fail_1;
1799 }
1800 }
1801 argvlist[argc] = NULL;
1802
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001803 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001804 envlist = PyMem_NEW(char *, i + 1);
1805 if (envlist == NULL) {
1806 PyErr_NoMemory();
1807 goto fail_1;
1808 }
1809 envc = 0;
1810 keys = PyMapping_Keys(env);
1811 vals = PyMapping_Values(env);
1812 if (!keys || !vals)
1813 goto fail_2;
1814
1815 for (pos = 0; pos < i; pos++) {
1816 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001817 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001818
1819 key = PyList_GetItem(keys, pos);
1820 val = PyList_GetItem(vals, pos);
1821 if (!key || !val)
1822 goto fail_2;
1823
Fred Drake661ea262000-10-24 19:57:45 +00001824 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1825 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001826 {
1827 goto fail_2;
1828 }
Tim Petersc8996f52001-12-03 20:41:00 +00001829 len = PyString_Size(key) + PyString_Size(val) + 2;
1830 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001831 if (p == NULL) {
1832 PyErr_NoMemory();
1833 goto fail_2;
1834 }
Tim Petersc8996f52001-12-03 20:41:00 +00001835 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001836 envlist[envc++] = p;
1837 }
1838 envlist[envc] = 0;
1839
Guido van Rossum246bc171999-02-01 23:54:31 +00001840 if (mode == _OLD_P_OVERLAY)
1841 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001842
1843 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001844 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001845 Py_END_ALLOW_THREADS
1846
Fred Drake699f3522000-06-29 21:12:41 +00001847 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001848 (void) posix_error();
1849 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001850#if SIZEOF_LONG == SIZEOF_VOID_P
1851 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001852#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001853 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001854#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001855
1856 fail_2:
1857 while (--envc >= 0)
1858 PyMem_DEL(envlist[envc]);
1859 PyMem_DEL(envlist);
1860 fail_1:
1861 PyMem_DEL(argvlist);
1862 Py_XDECREF(vals);
1863 Py_XDECREF(keys);
1864 return res;
1865}
1866#endif /* HAVE_SPAWNV */
1867
1868
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001869#ifdef HAVE_FORK1
1870static char posix_fork1__doc__[] =
1871"fork1() -> pid\n\
1872Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1873\n\
1874Return 0 to child process and PID of child to parent process.";
1875
1876static PyObject *
1877posix_fork1(self, args)
1878 PyObject *self;
1879 PyObject *args;
1880{
1881 int pid;
1882 if (!PyArg_ParseTuple(args, ":fork1"))
1883 return NULL;
1884 pid = fork1();
1885 if (pid == -1)
1886 return posix_error();
1887 PyOS_AfterFork();
1888 return PyInt_FromLong((long)pid);
1889}
1890#endif
1891
1892
Guido van Rossumad0ee831995-03-01 10:34:45 +00001893#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001894static char posix_fork__doc__[] =
1895"fork() -> pid\n\
1896Fork a child process.\n\
1897\n\
1898Return 0 to child process and PID of child to parent process.";
1899
Barry Warsaw53699e91996-12-10 23:23:01 +00001900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001901posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001902{
1903 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001904 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001905 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001906 pid = fork();
1907 if (pid == -1)
1908 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001909 if (pid == 0)
1910 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001911 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001912}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001913#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001914
Fred Drake8cef4cf2000-06-28 16:40:38 +00001915#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1916#ifdef HAVE_PTY_H
1917#include <pty.h>
1918#else
1919#ifdef HAVE_LIBUTIL_H
1920#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001921#endif /* HAVE_LIBUTIL_H */
1922#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001923#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001924
Thomas Wouters70c21a12000-07-14 14:28:33 +00001925#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001926static char posix_openpty__doc__[] =
1927"openpty() -> (master_fd, slave_fd)\n\
1928Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1929
1930static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001931posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001932{
1933 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001934#ifndef HAVE_OPENPTY
1935 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001936#endif
1937
Fred Drake8cef4cf2000-06-28 16:40:38 +00001938 if (!PyArg_ParseTuple(args, ":openpty"))
1939 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001940
1941#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001942 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1943 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001944#else
1945 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1946 if (slave_name == NULL)
1947 return posix_error();
1948
1949 slave_fd = open(slave_name, O_RDWR);
1950 if (slave_fd < 0)
1951 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001952#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001953
Fred Drake8cef4cf2000-06-28 16:40:38 +00001954 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001955
Fred Drake8cef4cf2000-06-28 16:40:38 +00001956}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001957#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001958
1959#ifdef HAVE_FORKPTY
1960static char posix_forkpty__doc__[] =
1961"forkpty() -> (pid, master_fd)\n\
1962Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1963Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1964To both, return fd of newly opened pseudo-terminal.\n";
1965
1966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001967posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001968{
1969 int master_fd, pid;
1970
1971 if (!PyArg_ParseTuple(args, ":forkpty"))
1972 return NULL;
1973 pid = forkpty(&master_fd, NULL, NULL, NULL);
1974 if (pid == -1)
1975 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001976 if (pid == 0)
1977 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001978 return Py_BuildValue("(ii)", pid, master_fd);
1979}
1980#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001981
Guido van Rossumad0ee831995-03-01 10:34:45 +00001982#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001983static char posix_getegid__doc__[] =
1984"getegid() -> egid\n\
1985Return the current process's effective group id.";
1986
Barry Warsaw53699e91996-12-10 23:23:01 +00001987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001988posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001989{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001990 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001991 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001992 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001993}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001994#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001995
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001996
Guido van Rossumad0ee831995-03-01 10:34:45 +00001997#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001998static char posix_geteuid__doc__[] =
1999"geteuid() -> euid\n\
2000Return the current process's effective user id.";
2001
Barry Warsaw53699e91996-12-10 23:23:01 +00002002static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002003posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002004{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002005 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002006 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002007 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002008}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002009#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002011
Guido van Rossumad0ee831995-03-01 10:34:45 +00002012#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002013static char posix_getgid__doc__[] =
2014"getgid() -> gid\n\
2015Return the current process's group id.";
2016
Barry Warsaw53699e91996-12-10 23:23:01 +00002017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002018posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002019{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002020 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002021 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002022 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002023}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002024#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002026
2027static char posix_getpid__doc__[] =
2028"getpid() -> pid\n\
2029Return the current process id";
2030
Barry Warsaw53699e91996-12-10 23:23:01 +00002031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002032posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002033{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002034 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002035 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002036 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002037}
2038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002039
Fred Drakec9680921999-12-13 16:37:25 +00002040#ifdef HAVE_GETGROUPS
2041static char posix_getgroups__doc__[] = "\
2042getgroups() -> list of group IDs\n\
2043Return list of supplemental group IDs for the process.";
2044
2045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002046posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002047{
2048 PyObject *result = NULL;
2049
2050 if (PyArg_ParseTuple(args, ":getgroups")) {
2051#ifdef NGROUPS_MAX
2052#define MAX_GROUPS NGROUPS_MAX
2053#else
2054 /* defined to be 16 on Solaris7, so this should be a small number */
2055#define MAX_GROUPS 64
2056#endif
2057 gid_t grouplist[MAX_GROUPS];
2058 int n;
2059
2060 n = getgroups(MAX_GROUPS, grouplist);
2061 if (n < 0)
2062 posix_error();
2063 else {
2064 result = PyList_New(n);
2065 if (result != NULL) {
2066 PyObject *o;
2067 int i;
2068 for (i = 0; i < n; ++i) {
2069 o = PyInt_FromLong((long)grouplist[i]);
2070 if (o == NULL) {
2071 Py_DECREF(result);
2072 result = NULL;
2073 break;
2074 }
2075 PyList_SET_ITEM(result, i, o);
2076 }
2077 }
2078 }
2079 }
2080 return result;
2081}
2082#endif
2083
Guido van Rossumb6775db1994-08-01 11:34:53 +00002084#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002085static char posix_getpgrp__doc__[] =
2086"getpgrp() -> pgrp\n\
2087Return the current process group id.";
2088
Barry Warsaw53699e91996-12-10 23:23:01 +00002089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002090posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002091{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002092 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002093 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002094#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002095 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002096#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002097 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002098#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002099}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002100#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002101
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002102
Guido van Rossumb6775db1994-08-01 11:34:53 +00002103#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002104static char posix_setpgrp__doc__[] =
2105"setpgrp() -> None\n\
2106Make this process a session leader.";
2107
Barry Warsaw53699e91996-12-10 23:23:01 +00002108static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002109posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002110{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002111 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002112 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002113#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002114 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002115#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002116 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002117#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002118 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002119 Py_INCREF(Py_None);
2120 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002121}
2122
Guido van Rossumb6775db1994-08-01 11:34:53 +00002123#endif /* HAVE_SETPGRP */
2124
Guido van Rossumad0ee831995-03-01 10:34:45 +00002125#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002126static char posix_getppid__doc__[] =
2127"getppid() -> ppid\n\
2128Return the parent's process id.";
2129
Barry Warsaw53699e91996-12-10 23:23:01 +00002130static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002131posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002132{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002133 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002134 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002135 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002136}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002137#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002138
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002139
Fred Drake12c6e2d1999-12-14 21:25:03 +00002140#ifdef HAVE_GETLOGIN
2141static char posix_getlogin__doc__[] = "\
2142getlogin() -> string\n\
2143Return the actual login name.";
2144
2145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002146posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002147{
2148 PyObject *result = NULL;
2149
2150 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002151 char *name;
2152 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002153
Fred Drakea30680b2000-12-06 21:24:28 +00002154 errno = 0;
2155 name = getlogin();
2156 if (name == NULL) {
2157 if (errno)
2158 posix_error();
2159 else
2160 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002161 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002162 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002163 else
2164 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002165 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002166 }
2167 return result;
2168}
2169#endif
2170
Guido van Rossumad0ee831995-03-01 10:34:45 +00002171#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002172static char posix_getuid__doc__[] =
2173"getuid() -> uid\n\
2174Return the current process's user id.";
2175
Barry Warsaw53699e91996-12-10 23:23:01 +00002176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002177posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002178{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002179 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002180 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002181 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002182}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002183#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002184
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002185
Guido van Rossumad0ee831995-03-01 10:34:45 +00002186#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002187static char posix_kill__doc__[] =
2188"kill(pid, sig) -> None\n\
2189Kill a process with a signal.";
2190
Barry Warsaw53699e91996-12-10 23:23:01 +00002191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002192posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002193{
2194 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002195 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002196 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002197#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002198 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2199 APIRET rc;
2200 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002201 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002202
2203 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2204 APIRET rc;
2205 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002206 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002207
2208 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002209 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002210#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002211 if (kill(pid, sig) == -1)
2212 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002213#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002214 Py_INCREF(Py_None);
2215 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002216}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002217#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002218
Guido van Rossumc0125471996-06-28 18:55:32 +00002219#ifdef HAVE_PLOCK
2220
2221#ifdef HAVE_SYS_LOCK_H
2222#include <sys/lock.h>
2223#endif
2224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002225static char posix_plock__doc__[] =
2226"plock(op) -> None\n\
2227Lock program segments into memory.";
2228
Barry Warsaw53699e91996-12-10 23:23:01 +00002229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002230posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002231{
2232 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002233 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002234 return NULL;
2235 if (plock(op) == -1)
2236 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002237 Py_INCREF(Py_None);
2238 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002239}
2240#endif
2241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002242
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002243#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002244static char posix_popen__doc__[] =
2245"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2246Open a pipe to/from a command returning a file object.";
2247
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002248#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002249static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002250async_system(const char *command)
2251{
2252 char *p, errormsg[256], args[1024];
2253 RESULTCODES rcodes;
2254 APIRET rc;
2255 char *shell = getenv("COMSPEC");
2256 if (!shell)
2257 shell = "cmd";
2258
2259 strcpy(args, shell);
2260 p = &args[ strlen(args)+1 ];
2261 strcpy(p, "/c ");
2262 strcat(p, command);
2263 p += strlen(p) + 1;
2264 *p = '\0';
2265
2266 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002267 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002268 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002269 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002270 &rcodes, shell);
2271 return rc;
2272}
2273
Guido van Rossumd48f2521997-12-05 22:19:34 +00002274static FILE *
2275popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002276{
2277 HFILE rhan, whan;
2278 FILE *retfd = NULL;
2279 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2280
Guido van Rossumd48f2521997-12-05 22:19:34 +00002281 if (rc != NO_ERROR) {
2282 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002283 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002284 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002285
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002286 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2287 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002288
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002289 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2290 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002291
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002292 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2293 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002294
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002295 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002296 }
2297
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002298 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2299 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002300
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002301 if (rc == NO_ERROR)
2302 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2303
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002304 close(oldfd); /* And Close Saved STDOUT Handle */
2305 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002306
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002307 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2308 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002309
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002310 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2311 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002312
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002313 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2314 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002315
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002316 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002317 }
2318
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002319 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2320 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002321
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002322 if (rc == NO_ERROR)
2323 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2324
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002325 close(oldfd); /* And Close Saved STDIN Handle */
2326 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002327
Guido van Rossumd48f2521997-12-05 22:19:34 +00002328 } else {
2329 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002330 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002331 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002332}
2333
2334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002335posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002336{
2337 char *name;
2338 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002339 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002340 FILE *fp;
2341 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002342 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002343 return NULL;
2344 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002345 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002346 Py_END_ALLOW_THREADS
2347 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002348 return os2_error(err);
2349
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002350 f = PyFile_FromFile(fp, name, mode, fclose);
2351 if (f != NULL)
2352 PyFile_SetBufSize(f, bufsize);
2353 return f;
2354}
2355
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002356#elif defined(MS_WIN32)
2357
2358/*
2359 * Portable 'popen' replacement for Win32.
2360 *
2361 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2362 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002363 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002364 */
2365
2366#include <malloc.h>
2367#include <io.h>
2368#include <fcntl.h>
2369
2370/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2371#define POPEN_1 1
2372#define POPEN_2 2
2373#define POPEN_3 3
2374#define POPEN_4 4
2375
2376static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002377static int _PyPclose(FILE *file);
2378
2379/*
2380 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002381 * for use when retrieving the process exit code. See _PyPclose() below
2382 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002383 */
2384static PyObject *_PyPopenProcs = NULL;
2385
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002386
2387/* popen that works from a GUI.
2388 *
2389 * The result of this function is a pipe (file) connected to the
2390 * processes stdin or stdout, depending on the requested mode.
2391 */
2392
2393static PyObject *
2394posix_popen(PyObject *self, PyObject *args)
2395{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002396 PyObject *f, *s;
2397 int tm = 0;
2398
2399 char *cmdstring;
2400 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002401 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002402 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002403 return NULL;
2404
2405 s = PyTuple_New(0);
2406
2407 if (*mode == 'r')
2408 tm = _O_RDONLY;
2409 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002410 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002411 return NULL;
2412 } else
2413 tm = _O_WRONLY;
2414
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002415 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002416 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002417 return NULL;
2418 }
2419
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002420 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002421 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002422 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002423 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002424 else
2425 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2426
2427 return f;
2428}
2429
2430/* Variation on win32pipe.popen
2431 *
2432 * The result of this function is a pipe (file) connected to the
2433 * process's stdin, and a pipe connected to the process's stdout.
2434 */
2435
2436static PyObject *
2437win32_popen2(PyObject *self, PyObject *args)
2438{
2439 PyObject *f;
2440 int tm=0;
2441
2442 char *cmdstring;
2443 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002444 int bufsize = -1;
2445 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002446 return NULL;
2447
2448 if (*mode == 't')
2449 tm = _O_TEXT;
2450 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002451 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002452 return NULL;
2453 } else
2454 tm = _O_BINARY;
2455
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002456 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002457 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002458 return NULL;
2459 }
2460
2461 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002462
2463 return f;
2464}
2465
2466/*
2467 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002468 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002469 * The result of this function is 3 pipes - the process's stdin,
2470 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002471 */
2472
2473static PyObject *
2474win32_popen3(PyObject *self, PyObject *args)
2475{
2476 PyObject *f;
2477 int tm = 0;
2478
2479 char *cmdstring;
2480 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002481 int bufsize = -1;
2482 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002483 return NULL;
2484
2485 if (*mode == 't')
2486 tm = _O_TEXT;
2487 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002488 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002489 return NULL;
2490 } else
2491 tm = _O_BINARY;
2492
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002493 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002494 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002495 return NULL;
2496 }
2497
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002498 f = _PyPopen(cmdstring, tm, POPEN_3);
2499
2500 return f;
2501}
2502
2503/*
2504 * Variation on win32pipe.popen
2505 *
2506 * The result of this function is 2 pipes - the processes stdin,
2507 * and stdout+stderr combined as a single pipe.
2508 */
2509
2510static PyObject *
2511win32_popen4(PyObject *self, PyObject *args)
2512{
2513 PyObject *f;
2514 int tm = 0;
2515
2516 char *cmdstring;
2517 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002518 int bufsize = -1;
2519 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002520 return NULL;
2521
2522 if (*mode == 't')
2523 tm = _O_TEXT;
2524 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002525 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002526 return NULL;
2527 } else
2528 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002529
2530 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002531 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002532 return NULL;
2533 }
2534
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002535 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002536
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002537 return f;
2538}
2539
Mark Hammond08501372001-01-31 07:30:29 +00002540static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002541_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002542 HANDLE hStdin,
2543 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002544 HANDLE hStderr,
2545 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002546{
2547 PROCESS_INFORMATION piProcInfo;
2548 STARTUPINFO siStartInfo;
2549 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002550 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002551 int i;
2552 int x;
2553
2554 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002555 char *comshell;
2556
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002557 s1 = (char *)_alloca(i);
2558 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2559 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002560
2561 /* Explicitly check if we are using COMMAND.COM. If we are
2562 * then use the w9xpopen hack.
2563 */
2564 comshell = s1 + x;
2565 while (comshell >= s1 && *comshell != '\\')
2566 --comshell;
2567 ++comshell;
2568
2569 if (GetVersion() < 0x80000000 &&
2570 _stricmp(comshell, "command.com") != 0) {
2571 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002572 x = i + strlen(s3) + strlen(cmdstring) + 1;
2573 s2 = (char *)_alloca(x);
2574 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002575 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002576 }
2577 else {
2578 /*
Tim Peters402d5982001-08-27 06:37:48 +00002579 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2580 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002581 */
Mark Hammond08501372001-01-31 07:30:29 +00002582 char modulepath[_MAX_PATH];
2583 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002584 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2585 for (i = x = 0; modulepath[i]; i++)
2586 if (modulepath[i] == '\\')
2587 x = i+1;
2588 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002589 /* Create the full-name to w9xpopen, so we can test it exists */
2590 strncat(modulepath,
2591 szConsoleSpawn,
2592 (sizeof(modulepath)/sizeof(modulepath[0]))
2593 -strlen(modulepath));
2594 if (stat(modulepath, &statinfo) != 0) {
2595 /* Eeek - file-not-found - possibly an embedding
2596 situation - see if we can locate it in sys.prefix
2597 */
2598 strncpy(modulepath,
2599 Py_GetExecPrefix(),
2600 sizeof(modulepath)/sizeof(modulepath[0]));
2601 if (modulepath[strlen(modulepath)-1] != '\\')
2602 strcat(modulepath, "\\");
2603 strncat(modulepath,
2604 szConsoleSpawn,
2605 (sizeof(modulepath)/sizeof(modulepath[0]))
2606 -strlen(modulepath));
2607 /* No where else to look - raise an easily identifiable
2608 error, rather than leaving Windows to report
2609 "file not found" - as the user is probably blissfully
2610 unaware this shim EXE is used, and it will confuse them.
2611 (well, it confused me for a while ;-)
2612 */
2613 if (stat(modulepath, &statinfo) != 0) {
2614 PyErr_Format(PyExc_RuntimeError,
2615 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002616 "for popen to work with your shell "
2617 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002618 szConsoleSpawn);
2619 return FALSE;
2620 }
2621 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002622 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2623 strlen(modulepath) +
2624 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002625
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002626 s2 = (char *)_alloca(x);
2627 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002628 PyOS_snprintf(
2629 s2, x,
Mark Hammond08501372001-01-31 07:30:29 +00002630 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002631 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002632 s1,
2633 s3,
2634 cmdstring);
2635 }
2636 }
2637
2638 /* Could be an else here to try cmd.exe / command.com in the path
2639 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002640 else {
Tim Peters402d5982001-08-27 06:37:48 +00002641 PyErr_SetString(PyExc_RuntimeError,
2642 "Cannot locate a COMSPEC environment variable to "
2643 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002644 return FALSE;
2645 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002646
2647 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2648 siStartInfo.cb = sizeof(STARTUPINFO);
2649 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2650 siStartInfo.hStdInput = hStdin;
2651 siStartInfo.hStdOutput = hStdout;
2652 siStartInfo.hStdError = hStderr;
2653 siStartInfo.wShowWindow = SW_HIDE;
2654
2655 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002656 s2,
2657 NULL,
2658 NULL,
2659 TRUE,
2660 CREATE_NEW_CONSOLE,
2661 NULL,
2662 NULL,
2663 &siStartInfo,
2664 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002665 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002666 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002667
Mark Hammondb37a3732000-08-14 04:47:33 +00002668 /* Return process handle */
2669 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002670 return TRUE;
2671 }
Tim Peters402d5982001-08-27 06:37:48 +00002672 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002673 return FALSE;
2674}
2675
2676/* The following code is based off of KB: Q190351 */
2677
2678static PyObject *
2679_PyPopen(char *cmdstring, int mode, int n)
2680{
2681 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2682 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002683 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002684
2685 SECURITY_ATTRIBUTES saAttr;
2686 BOOL fSuccess;
2687 int fd1, fd2, fd3;
2688 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002689 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002690 PyObject *f;
2691
2692 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2693 saAttr.bInheritHandle = TRUE;
2694 saAttr.lpSecurityDescriptor = NULL;
2695
2696 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2697 return win32_error("CreatePipe", NULL);
2698
2699 /* Create new output read handle and the input write handle. Set
2700 * the inheritance properties to FALSE. Otherwise, the child inherits
2701 * the these handles; resulting in non-closeable handles to the pipes
2702 * being created. */
2703 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002704 GetCurrentProcess(), &hChildStdinWrDup, 0,
2705 FALSE,
2706 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002707 if (!fSuccess)
2708 return win32_error("DuplicateHandle", NULL);
2709
2710 /* Close the inheritable version of ChildStdin
2711 that we're using. */
2712 CloseHandle(hChildStdinWr);
2713
2714 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2715 return win32_error("CreatePipe", NULL);
2716
2717 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002718 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2719 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002720 if (!fSuccess)
2721 return win32_error("DuplicateHandle", NULL);
2722
2723 /* Close the inheritable version of ChildStdout
2724 that we're using. */
2725 CloseHandle(hChildStdoutRd);
2726
2727 if (n != POPEN_4) {
2728 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2729 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002730 fSuccess = DuplicateHandle(GetCurrentProcess(),
2731 hChildStderrRd,
2732 GetCurrentProcess(),
2733 &hChildStderrRdDup, 0,
2734 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002735 if (!fSuccess)
2736 return win32_error("DuplicateHandle", NULL);
2737 /* Close the inheritable version of ChildStdErr that we're using. */
2738 CloseHandle(hChildStderrRd);
2739 }
2740
2741 switch (n) {
2742 case POPEN_1:
2743 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2744 case _O_WRONLY | _O_TEXT:
2745 /* Case for writing to child Stdin in text mode. */
2746 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2747 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002748 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002749 PyFile_SetBufSize(f, 0);
2750 /* We don't care about these pipes anymore, so close them. */
2751 CloseHandle(hChildStdoutRdDup);
2752 CloseHandle(hChildStderrRdDup);
2753 break;
2754
2755 case _O_RDONLY | _O_TEXT:
2756 /* Case for reading from child Stdout in text mode. */
2757 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2758 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002759 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002760 PyFile_SetBufSize(f, 0);
2761 /* We don't care about these pipes anymore, so close them. */
2762 CloseHandle(hChildStdinWrDup);
2763 CloseHandle(hChildStderrRdDup);
2764 break;
2765
2766 case _O_RDONLY | _O_BINARY:
2767 /* Case for readinig from child Stdout in binary mode. */
2768 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2769 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002770 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002771 PyFile_SetBufSize(f, 0);
2772 /* We don't care about these pipes anymore, so close them. */
2773 CloseHandle(hChildStdinWrDup);
2774 CloseHandle(hChildStderrRdDup);
2775 break;
2776
2777 case _O_WRONLY | _O_BINARY:
2778 /* Case for writing to child Stdin in binary mode. */
2779 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2780 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002781 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002782 PyFile_SetBufSize(f, 0);
2783 /* We don't care about these pipes anymore, so close them. */
2784 CloseHandle(hChildStdoutRdDup);
2785 CloseHandle(hChildStderrRdDup);
2786 break;
2787 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002788 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002789 break;
2790
2791 case POPEN_2:
2792 case POPEN_4:
2793 {
2794 char *m1, *m2;
2795 PyObject *p1, *p2;
2796
2797 if (mode && _O_TEXT) {
2798 m1 = "r";
2799 m2 = "w";
2800 } else {
2801 m1 = "rb";
2802 m2 = "wb";
2803 }
2804
2805 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2806 f1 = _fdopen(fd1, m2);
2807 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2808 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002809 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002810 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002811 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002812 PyFile_SetBufSize(p2, 0);
2813
2814 if (n != 4)
2815 CloseHandle(hChildStderrRdDup);
2816
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002817 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002818 Py_XDECREF(p1);
2819 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002820 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002821 break;
2822 }
2823
2824 case POPEN_3:
2825 {
2826 char *m1, *m2;
2827 PyObject *p1, *p2, *p3;
2828
2829 if (mode && _O_TEXT) {
2830 m1 = "r";
2831 m2 = "w";
2832 } else {
2833 m1 = "rb";
2834 m2 = "wb";
2835 }
2836
2837 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2838 f1 = _fdopen(fd1, m2);
2839 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2840 f2 = _fdopen(fd2, m1);
2841 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2842 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002843 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002844 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2845 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002846 PyFile_SetBufSize(p1, 0);
2847 PyFile_SetBufSize(p2, 0);
2848 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002849 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002850 Py_XDECREF(p1);
2851 Py_XDECREF(p2);
2852 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002853 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002854 break;
2855 }
2856 }
2857
2858 if (n == POPEN_4) {
2859 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002860 hChildStdinRd,
2861 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002862 hChildStdoutWr,
2863 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002864 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002865 }
2866 else {
2867 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002868 hChildStdinRd,
2869 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002870 hChildStderrWr,
2871 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002872 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002873 }
2874
Mark Hammondb37a3732000-08-14 04:47:33 +00002875 /*
2876 * Insert the files we've created into the process dictionary
2877 * all referencing the list with the process handle and the
2878 * initial number of files (see description below in _PyPclose).
2879 * Since if _PyPclose later tried to wait on a process when all
2880 * handles weren't closed, it could create a deadlock with the
2881 * child, we spend some energy here to try to ensure that we
2882 * either insert all file handles into the dictionary or none
2883 * at all. It's a little clumsy with the various popen modes
2884 * and variable number of files involved.
2885 */
2886 if (!_PyPopenProcs) {
2887 _PyPopenProcs = PyDict_New();
2888 }
2889
2890 if (_PyPopenProcs) {
2891 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2892 int ins_rc[3];
2893
2894 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2895 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2896
2897 procObj = PyList_New(2);
2898 hProcessObj = PyLong_FromVoidPtr(hProcess);
2899 intObj = PyInt_FromLong(file_count);
2900
2901 if (procObj && hProcessObj && intObj) {
2902 PyList_SetItem(procObj,0,hProcessObj);
2903 PyList_SetItem(procObj,1,intObj);
2904
2905 fileObj[0] = PyLong_FromVoidPtr(f1);
2906 if (fileObj[0]) {
2907 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2908 fileObj[0],
2909 procObj);
2910 }
2911 if (file_count >= 2) {
2912 fileObj[1] = PyLong_FromVoidPtr(f2);
2913 if (fileObj[1]) {
2914 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2915 fileObj[1],
2916 procObj);
2917 }
2918 }
2919 if (file_count >= 3) {
2920 fileObj[2] = PyLong_FromVoidPtr(f3);
2921 if (fileObj[2]) {
2922 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2923 fileObj[2],
2924 procObj);
2925 }
2926 }
2927
2928 if (ins_rc[0] < 0 || !fileObj[0] ||
2929 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2930 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2931 /* Something failed - remove any dictionary
2932 * entries that did make it.
2933 */
2934 if (!ins_rc[0] && fileObj[0]) {
2935 PyDict_DelItem(_PyPopenProcs,
2936 fileObj[0]);
2937 }
2938 if (!ins_rc[1] && fileObj[1]) {
2939 PyDict_DelItem(_PyPopenProcs,
2940 fileObj[1]);
2941 }
2942 if (!ins_rc[2] && fileObj[2]) {
2943 PyDict_DelItem(_PyPopenProcs,
2944 fileObj[2]);
2945 }
2946 }
2947 }
2948
2949 /*
2950 * Clean up our localized references for the dictionary keys
2951 * and value since PyDict_SetItem will Py_INCREF any copies
2952 * that got placed in the dictionary.
2953 */
2954 Py_XDECREF(procObj);
2955 Py_XDECREF(fileObj[0]);
2956 Py_XDECREF(fileObj[1]);
2957 Py_XDECREF(fileObj[2]);
2958 }
2959
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002960 /* Child is launched. Close the parents copy of those pipe
2961 * handles that only the child should have open. You need to
2962 * make sure that no handles to the write end of the output pipe
2963 * are maintained in this process or else the pipe will not close
2964 * when the child process exits and the ReadFile will hang. */
2965
2966 if (!CloseHandle(hChildStdinRd))
2967 return win32_error("CloseHandle", NULL);
2968
2969 if (!CloseHandle(hChildStdoutWr))
2970 return win32_error("CloseHandle", NULL);
2971
2972 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2973 return win32_error("CloseHandle", NULL);
2974
2975 return f;
2976}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002977
2978/*
2979 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2980 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002981 *
2982 * This function uses the _PyPopenProcs dictionary in order to map the
2983 * input file pointer to information about the process that was
2984 * originally created by the popen* call that created the file pointer.
2985 * The dictionary uses the file pointer as a key (with one entry
2986 * inserted for each file returned by the original popen* call) and a
2987 * single list object as the value for all files from a single call.
2988 * The list object contains the Win32 process handle at [0], and a file
2989 * count at [1], which is initialized to the total number of file
2990 * handles using that list.
2991 *
2992 * This function closes whichever handle it is passed, and decrements
2993 * the file count in the dictionary for the process handle pointed to
2994 * by this file. On the last close (when the file count reaches zero),
2995 * this function will wait for the child process and then return its
2996 * exit code as the result of the close() operation. This permits the
2997 * files to be closed in any order - it is always the close() of the
2998 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002999 */
Tim Peters736aa322000-09-01 06:51:24 +00003000
3001 /* RED_FLAG 31-Aug-2000 Tim
3002 * This is always called (today!) between a pair of
3003 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3004 * macros. So the thread running this has no valid thread state, as
3005 * far as Python is concerned. However, this calls some Python API
3006 * functions that cannot be called safely without a valid thread
3007 * state, in particular PyDict_GetItem.
3008 * As a temporary hack (although it may last for years ...), we
3009 * *rely* on not having a valid thread state in this function, in
3010 * order to create our own "from scratch".
3011 * This will deadlock if _PyPclose is ever called by a thread
3012 * holding the global lock.
3013 */
3014
Fredrik Lundh56055a42000-07-23 19:47:12 +00003015static int _PyPclose(FILE *file)
3016{
Fredrik Lundh20318932000-07-26 17:29:12 +00003017 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003018 DWORD exit_code;
3019 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003020 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3021 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003022#ifdef WITH_THREAD
3023 PyInterpreterState* pInterpreterState;
3024 PyThreadState* pThreadState;
3025#endif
3026
Fredrik Lundh20318932000-07-26 17:29:12 +00003027 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003028 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003029 */
3030 result = fclose(file);
3031
Tim Peters736aa322000-09-01 06:51:24 +00003032#ifdef WITH_THREAD
3033 /* Bootstrap a valid thread state into existence. */
3034 pInterpreterState = PyInterpreterState_New();
3035 if (!pInterpreterState) {
3036 /* Well, we're hosed now! We don't have a thread
3037 * state, so can't call a nice error routine, or raise
3038 * an exception. Just die.
3039 */
3040 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003041 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003042 return -1; /* unreachable */
3043 }
3044 pThreadState = PyThreadState_New(pInterpreterState);
3045 if (!pThreadState) {
3046 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003047 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003048 return -1; /* unreachable */
3049 }
3050 /* Grab the global lock. Note that this will deadlock if the
3051 * current thread already has the lock! (see RED_FLAG comments
3052 * before this function)
3053 */
3054 PyEval_RestoreThread(pThreadState);
3055#endif
3056
Fredrik Lundh56055a42000-07-23 19:47:12 +00003057 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003058 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3059 (procObj = PyDict_GetItem(_PyPopenProcs,
3060 fileObj)) != NULL &&
3061 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3062 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3063
3064 hProcess = PyLong_AsVoidPtr(hProcessObj);
3065 file_count = PyInt_AsLong(intObj);
3066
3067 if (file_count > 1) {
3068 /* Still other files referencing process */
3069 file_count--;
3070 PyList_SetItem(procObj,1,
3071 PyInt_FromLong(file_count));
3072 } else {
3073 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003074 if (result != EOF &&
3075 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3076 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003077 /* Possible truncation here in 16-bit environments, but
3078 * real exit codes are just the lower byte in any event.
3079 */
3080 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003081 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003082 /* Indicate failure - this will cause the file object
3083 * to raise an I/O error and translate the last Win32
3084 * error code from errno. We do have a problem with
3085 * last errors that overlap the normal errno table,
3086 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003087 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003088 if (result != EOF) {
3089 /* If the error wasn't from the fclose(), then
3090 * set errno for the file object error handling.
3091 */
3092 errno = GetLastError();
3093 }
3094 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003095 }
3096
3097 /* Free up the native handle at this point */
3098 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003099 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003100
Mark Hammondb37a3732000-08-14 04:47:33 +00003101 /* Remove this file pointer from dictionary */
3102 PyDict_DelItem(_PyPopenProcs, fileObj);
3103
3104 if (PyDict_Size(_PyPopenProcs) == 0) {
3105 Py_DECREF(_PyPopenProcs);
3106 _PyPopenProcs = NULL;
3107 }
3108
3109 } /* if object retrieval ok */
3110
3111 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003112 } /* if _PyPopenProcs */
3113
Tim Peters736aa322000-09-01 06:51:24 +00003114#ifdef WITH_THREAD
3115 /* Tear down the thread & interpreter states.
3116 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003117 * call the thread clear & delete functions, and indeed insist on
3118 * doing that themselves. The lock must be held during the clear, but
3119 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003120 */
3121 PyInterpreterState_Clear(pInterpreterState);
3122 PyEval_ReleaseThread(pThreadState);
3123 PyInterpreterState_Delete(pInterpreterState);
3124#endif
3125
Fredrik Lundh56055a42000-07-23 19:47:12 +00003126 return result;
3127}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003128
3129#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003131posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003132{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003133 char *name;
3134 char *mode = "r";
3135 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003136 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003137 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003138 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003139 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003140 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003141 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003142 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003143 if (fp == NULL)
3144 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003145 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003146 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003147 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003148 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003149}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003150#endif
3151
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003152#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003154
Guido van Rossumb6775db1994-08-01 11:34:53 +00003155#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003156static char posix_setuid__doc__[] =
3157"setuid(uid) -> None\n\
3158Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003160posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003161{
3162 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003163 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003164 return NULL;
3165 if (setuid(uid) < 0)
3166 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003167 Py_INCREF(Py_None);
3168 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003169}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003170#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003171
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003172
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003173#ifdef HAVE_SETEUID
3174static char posix_seteuid__doc__[] =
3175"seteuid(uid) -> None\n\
3176Set the current process's effective user id.";
3177static PyObject *
3178posix_seteuid (PyObject *self, PyObject *args)
3179{
3180 int euid;
3181 if (!PyArg_ParseTuple(args, "i", &euid)) {
3182 return NULL;
3183 } else if (seteuid(euid) < 0) {
3184 return posix_error();
3185 } else {
3186 Py_INCREF(Py_None);
3187 return Py_None;
3188 }
3189}
3190#endif /* HAVE_SETEUID */
3191
3192#ifdef HAVE_SETEGID
3193static char posix_setegid__doc__[] =
3194"setegid(gid) -> None\n\
3195Set the current process's effective group id.";
3196static PyObject *
3197posix_setegid (PyObject *self, PyObject *args)
3198{
3199 int egid;
3200 if (!PyArg_ParseTuple(args, "i", &egid)) {
3201 return NULL;
3202 } else if (setegid(egid) < 0) {
3203 return posix_error();
3204 } else {
3205 Py_INCREF(Py_None);
3206 return Py_None;
3207 }
3208}
3209#endif /* HAVE_SETEGID */
3210
3211#ifdef HAVE_SETREUID
3212static char posix_setreuid__doc__[] =
3213"seteuid(ruid, euid) -> None\n\
3214Set the current process's real and effective user ids.";
3215static PyObject *
3216posix_setreuid (PyObject *self, PyObject *args)
3217{
3218 int ruid, euid;
3219 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3220 return NULL;
3221 } else if (setreuid(ruid, euid) < 0) {
3222 return posix_error();
3223 } else {
3224 Py_INCREF(Py_None);
3225 return Py_None;
3226 }
3227}
3228#endif /* HAVE_SETREUID */
3229
3230#ifdef HAVE_SETREGID
3231static char posix_setregid__doc__[] =
3232"setegid(rgid, egid) -> None\n\
3233Set the current process's real and effective group ids.";
3234static PyObject *
3235posix_setregid (PyObject *self, PyObject *args)
3236{
3237 int rgid, egid;
3238 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3239 return NULL;
3240 } else if (setregid(rgid, egid) < 0) {
3241 return posix_error();
3242 } else {
3243 Py_INCREF(Py_None);
3244 return Py_None;
3245 }
3246}
3247#endif /* HAVE_SETREGID */
3248
Guido van Rossumb6775db1994-08-01 11:34:53 +00003249#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003250static char posix_setgid__doc__[] =
3251"setgid(gid) -> None\n\
3252Set the current process's group id.";
3253
Barry Warsaw53699e91996-12-10 23:23:01 +00003254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003255posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003256{
3257 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003258 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003259 return NULL;
3260 if (setgid(gid) < 0)
3261 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003262 Py_INCREF(Py_None);
3263 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003264}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003265#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003266
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003267#ifdef HAVE_SETGROUPS
3268static char posix_setgroups__doc__[] =
3269"setgroups(list) -> None\n\
3270Set the groups of the current process to list.";
3271
3272static PyObject *
3273posix_setgroups(PyObject *self, PyObject *args)
3274{
3275 PyObject *groups;
3276 int i, len;
3277 gid_t grouplist[MAX_GROUPS];
3278
3279 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3280 return NULL;
3281 if (!PySequence_Check(groups)) {
3282 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3283 return NULL;
3284 }
3285 len = PySequence_Size(groups);
3286 if (len > MAX_GROUPS) {
3287 PyErr_SetString(PyExc_ValueError, "too many groups");
3288 return NULL;
3289 }
3290 for(i = 0; i < len; i++) {
3291 PyObject *elem;
3292 elem = PySequence_GetItem(groups, i);
3293 if (!elem)
3294 return NULL;
3295 if (!PyInt_Check(elem)) {
3296 PyErr_SetString(PyExc_TypeError,
3297 "groups must be integers");
3298 Py_DECREF(elem);
3299 return NULL;
3300 }
3301 /* XXX: check that value fits into gid_t. */
3302 grouplist[i] = PyInt_AsLong(elem);
3303 Py_DECREF(elem);
3304 }
3305
3306 if (setgroups(len, grouplist) < 0)
3307 return posix_error();
3308 Py_INCREF(Py_None);
3309 return Py_None;
3310}
3311#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003312
Guido van Rossumb6775db1994-08-01 11:34:53 +00003313#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003314static char posix_waitpid__doc__[] =
3315"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003316Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003317
Barry Warsaw53699e91996-12-10 23:23:01 +00003318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003319posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003320{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003321 int pid, options;
3322#ifdef UNION_WAIT
3323 union wait status;
3324#define status_i (status.w_status)
3325#else
3326 int status;
3327#define status_i status
3328#endif
3329 status_i = 0;
3330
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003331 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003332 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003333 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003334#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003335 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003336#else
3337 pid = waitpid(pid, &status, options);
3338#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003339 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003340 if (pid == -1)
3341 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003342 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003343 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003344}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003345#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003346
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003347
Guido van Rossumad0ee831995-03-01 10:34:45 +00003348#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003349static char posix_wait__doc__[] =
3350"wait() -> (pid, status)\n\
3351Wait for completion of a child process.";
3352
Barry Warsaw53699e91996-12-10 23:23:01 +00003353static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003354posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003355{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003356 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003357#ifdef UNION_WAIT
3358 union wait status;
3359#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003360#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003361 int status;
3362#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003363#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003364 if (!PyArg_ParseTuple(args, ":wait"))
3365 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003366 status_i = 0;
3367 Py_BEGIN_ALLOW_THREADS
3368 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003369 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003370 if (pid == -1)
3371 return posix_error();
3372 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003373 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003374#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003375}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003376#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003377
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003378
3379static char posix_lstat__doc__[] =
3380"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3381Like stat(path), but do not follow symbolic links.";
3382
Barry Warsaw53699e91996-12-10 23:23:01 +00003383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003384posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003385{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003386#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003387 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003388#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003389 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003390#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003391}
3392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003393
Guido van Rossumb6775db1994-08-01 11:34:53 +00003394#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003395static char posix_readlink__doc__[] =
3396"readlink(path) -> path\n\
3397Return a string representing the path to which the symbolic link points.";
3398
Barry Warsaw53699e91996-12-10 23:23:01 +00003399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003400posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003401{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003402 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003403 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003404 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003405 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003406 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003407 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003408 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003409 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003410 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003411 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003412 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003413}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003414#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003416
Guido van Rossumb6775db1994-08-01 11:34:53 +00003417#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003418static char posix_symlink__doc__[] =
3419"symlink(src, dst) -> None\n\
3420Create a symbolic link.";
3421
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003422static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003423posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003424{
Mark Hammondef8b6542001-05-13 08:04:26 +00003425 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003426}
3427#endif /* HAVE_SYMLINK */
3428
3429
3430#ifdef HAVE_TIMES
3431#ifndef HZ
3432#define HZ 60 /* Universal constant :-) */
3433#endif /* HZ */
3434
Guido van Rossumd48f2521997-12-05 22:19:34 +00003435#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3436static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003437system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003438{
3439 ULONG value = 0;
3440
3441 Py_BEGIN_ALLOW_THREADS
3442 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3443 Py_END_ALLOW_THREADS
3444
3445 return value;
3446}
3447
3448static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003449posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003450{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003451 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003452 return NULL;
3453
3454 /* Currently Only Uptime is Provided -- Others Later */
3455 return Py_BuildValue("ddddd",
3456 (double)0 /* t.tms_utime / HZ */,
3457 (double)0 /* t.tms_stime / HZ */,
3458 (double)0 /* t.tms_cutime / HZ */,
3459 (double)0 /* t.tms_cstime / HZ */,
3460 (double)system_uptime() / 1000);
3461}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003462#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003464posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003465{
3466 struct tms t;
3467 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003468 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003469 return NULL;
3470 errno = 0;
3471 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003472 if (c == (clock_t) -1)
3473 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003474 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003475 (double)t.tms_utime / HZ,
3476 (double)t.tms_stime / HZ,
3477 (double)t.tms_cutime / HZ,
3478 (double)t.tms_cstime / HZ,
3479 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003480}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003481#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003482#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003483
3484
Guido van Rossum87755a21996-09-07 00:59:43 +00003485#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003486#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003488posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003489{
3490 FILETIME create, exit, kernel, user;
3491 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003492 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003493 return NULL;
3494 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003495 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3496 /* The fields of a FILETIME structure are the hi and lo part
3497 of a 64-bit value expressed in 100 nanosecond units.
3498 1e7 is one second in such units; 1e-7 the inverse.
3499 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3500 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003501 return Py_BuildValue(
3502 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003503 (double)(kernel.dwHighDateTime*429.4967296 +
3504 kernel.dwLowDateTime*1e-7),
3505 (double)(user.dwHighDateTime*429.4967296 +
3506 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003507 (double)0,
3508 (double)0,
3509 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003510}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003511#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003512
3513#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003514static char posix_times__doc__[] =
3515"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3516Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003517#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003519
Guido van Rossumb6775db1994-08-01 11:34:53 +00003520#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003521static char posix_setsid__doc__[] =
3522"setsid() -> None\n\
3523Call the system call setsid().";
3524
Barry Warsaw53699e91996-12-10 23:23:01 +00003525static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003526posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003527{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003528 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003529 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003530 if (setsid() < 0)
3531 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003532 Py_INCREF(Py_None);
3533 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003534}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003535#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003536
Guido van Rossumb6775db1994-08-01 11:34:53 +00003537#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003538static char posix_setpgid__doc__[] =
3539"setpgid(pid, pgrp) -> None\n\
3540Call the system call setpgid().";
3541
Barry Warsaw53699e91996-12-10 23:23:01 +00003542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003543posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003544{
3545 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003546 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003547 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003548 if (setpgid(pid, pgrp) < 0)
3549 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003550 Py_INCREF(Py_None);
3551 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003552}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003553#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003555
Guido van Rossumb6775db1994-08-01 11:34:53 +00003556#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003557static char posix_tcgetpgrp__doc__[] =
3558"tcgetpgrp(fd) -> pgid\n\
3559Return the process group associated with the terminal given by a fd.";
3560
Barry Warsaw53699e91996-12-10 23:23:01 +00003561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003562posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003563{
3564 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003565 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003566 return NULL;
3567 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003568 if (pgid < 0)
3569 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003570 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003571}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003572#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003573
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003574
Guido van Rossumb6775db1994-08-01 11:34:53 +00003575#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003576static char posix_tcsetpgrp__doc__[] =
3577"tcsetpgrp(fd, pgid) -> None\n\
3578Set the process group associated with the terminal given by a fd.";
3579
Barry Warsaw53699e91996-12-10 23:23:01 +00003580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003581posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003582{
3583 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003584 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003585 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003586 if (tcsetpgrp(fd, pgid) < 0)
3587 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003588 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003589 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003590}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003591#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003592
Guido van Rossum687dd131993-05-17 08:34:16 +00003593/* Functions acting on file descriptors */
3594
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003595static char posix_open__doc__[] =
3596"open(filename, flag [, mode=0777]) -> fd\n\
3597Open a file (for low level IO).";
3598
Barry Warsaw53699e91996-12-10 23:23:01 +00003599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003600posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003601{
Mark Hammondef8b6542001-05-13 08:04:26 +00003602 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003603 int flag;
3604 int mode = 0777;
3605 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003606 if (!PyArg_ParseTuple(args, "eti|i",
3607 Py_FileSystemDefaultEncoding, &file,
3608 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003609 return NULL;
3610
Barry Warsaw53699e91996-12-10 23:23:01 +00003611 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003612 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003613 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003614 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003615 return posix_error_with_allocated_filename(file);
3616 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003617 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003618}
3619
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003620
3621static char posix_close__doc__[] =
3622"close(fd) -> None\n\
3623Close a file descriptor (for low level IO).";
3624
Barry Warsaw53699e91996-12-10 23:23:01 +00003625static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003626posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003627{
3628 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003629 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003630 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003631 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003632 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003633 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003634 if (res < 0)
3635 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003636 Py_INCREF(Py_None);
3637 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003638}
3639
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003640
3641static char posix_dup__doc__[] =
3642"dup(fd) -> fd2\n\
3643Return a duplicate of a file descriptor.";
3644
Barry Warsaw53699e91996-12-10 23:23:01 +00003645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003646posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003647{
3648 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003649 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003650 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003651 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003652 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003653 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003654 if (fd < 0)
3655 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003656 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003657}
3658
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003659
3660static char posix_dup2__doc__[] =
3661"dup2(fd, fd2) -> None\n\
3662Duplicate file descriptor.";
3663
Barry Warsaw53699e91996-12-10 23:23:01 +00003664static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003665posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003666{
3667 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003668 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003669 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003670 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003671 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003672 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003673 if (res < 0)
3674 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003675 Py_INCREF(Py_None);
3676 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003677}
3678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003679
3680static char posix_lseek__doc__[] =
3681"lseek(fd, pos, how) -> newpos\n\
3682Set the current position of a file descriptor.";
3683
Barry Warsaw53699e91996-12-10 23:23:01 +00003684static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003685posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003686{
3687 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003688#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003689 LONG_LONG pos, res;
3690#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003691 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003692#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003693 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003694 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003695 return NULL;
3696#ifdef SEEK_SET
3697 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3698 switch (how) {
3699 case 0: how = SEEK_SET; break;
3700 case 1: how = SEEK_CUR; break;
3701 case 2: how = SEEK_END; break;
3702 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003703#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003704
3705#if !defined(HAVE_LARGEFILE_SUPPORT)
3706 pos = PyInt_AsLong(posobj);
3707#else
3708 pos = PyLong_Check(posobj) ?
3709 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3710#endif
3711 if (PyErr_Occurred())
3712 return NULL;
3713
Barry Warsaw53699e91996-12-10 23:23:01 +00003714 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003715#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003716 res = _lseeki64(fd, pos, how);
3717#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003718 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003719#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003720 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003721 if (res < 0)
3722 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003723
3724#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003725 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003726#else
3727 return PyLong_FromLongLong(res);
3728#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003729}
3730
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003731
3732static char posix_read__doc__[] =
3733"read(fd, buffersize) -> string\n\
3734Read a file descriptor.";
3735
Barry Warsaw53699e91996-12-10 23:23:01 +00003736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003737posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003738{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003739 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003740 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003741 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003742 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003743 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003744 if (buffer == NULL)
3745 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003746 Py_BEGIN_ALLOW_THREADS
3747 n = read(fd, PyString_AsString(buffer), size);
3748 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003749 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003750 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003751 return posix_error();
3752 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003753 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003754 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003755 return buffer;
3756}
3757
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003758
3759static char posix_write__doc__[] =
3760"write(fd, string) -> byteswritten\n\
3761Write a string to a file descriptor.";
3762
Barry Warsaw53699e91996-12-10 23:23:01 +00003763static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003764posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003765{
3766 int fd, size;
3767 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003768 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003769 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003770 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003771 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003772 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003773 if (size < 0)
3774 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003775 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003776}
3777
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003778
3779static char posix_fstat__doc__[]=
3780"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3781Like stat(), but for an open file descriptor.";
3782
Barry Warsaw53699e91996-12-10 23:23:01 +00003783static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003784posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003785{
3786 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003787 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003788 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003789 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003790 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003791 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003792 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003793 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003794 if (res != 0)
3795 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003796
3797 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003798}
3799
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003800
3801static char posix_fdopen__doc__[] =
3802"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3803Return an open file object connected to a file descriptor.";
3804
Barry Warsaw53699e91996-12-10 23:23:01 +00003805static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003806posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003807{
Guido van Rossum687dd131993-05-17 08:34:16 +00003808 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003809 char *mode = "r";
3810 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003811 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003812 PyObject *f;
3813 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003814 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003815
Barry Warsaw53699e91996-12-10 23:23:01 +00003816 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003817 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003818 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003819 if (fp == NULL)
3820 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003821 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003822 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003823 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003824 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003825}
3826
Skip Montanaro1517d842000-07-19 14:34:14 +00003827static char posix_isatty__doc__[] =
3828"isatty(fd) -> Boolean\n\
3829Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003830connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003831
3832static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003833posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003834{
3835 int fd;
3836 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3837 return NULL;
3838 return Py_BuildValue("i", isatty(fd));
3839}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003840
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003841#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003842static char posix_pipe__doc__[] =
3843"pipe() -> (read_end, write_end)\n\
3844Create a pipe.";
3845
Barry Warsaw53699e91996-12-10 23:23:01 +00003846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003847posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003848{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003849#if defined(PYOS_OS2)
3850 HFILE read, write;
3851 APIRET rc;
3852
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003853 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003854 return NULL;
3855
3856 Py_BEGIN_ALLOW_THREADS
3857 rc = DosCreatePipe( &read, &write, 4096);
3858 Py_END_ALLOW_THREADS
3859 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003860 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003861
3862 return Py_BuildValue("(ii)", read, write);
3863#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003864#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003865 int fds[2];
3866 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003867 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003868 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003869 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003870 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003871 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003872 if (res != 0)
3873 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003874 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003875#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003876 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003877 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003878 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003879 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003880 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003881 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003882 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003883 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003884 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003885 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003886 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3887 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003888 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003889#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003890#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003891}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003892#endif /* HAVE_PIPE */
3893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003894
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003895#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003896static char posix_mkfifo__doc__[] =
3897"mkfifo(file, [, mode=0666]) -> None\n\
3898Create a FIFO (a POSIX named pipe).";
3899
Barry Warsaw53699e91996-12-10 23:23:01 +00003900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003901posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003902{
3903 char *file;
3904 int mode = 0666;
3905 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003906 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003907 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003908 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003909 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003910 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003911 if (res < 0)
3912 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003913 Py_INCREF(Py_None);
3914 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003915}
3916#endif
3917
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003918
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003919#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003920static char posix_ftruncate__doc__[] =
3921"ftruncate(fd, length) -> None\n\
3922Truncate a file to a specified length.";
3923
Barry Warsaw53699e91996-12-10 23:23:01 +00003924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003925posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003926{
3927 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003928 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003929 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003930 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003931
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003932 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003933 return NULL;
3934
3935#if !defined(HAVE_LARGEFILE_SUPPORT)
3936 length = PyInt_AsLong(lenobj);
3937#else
3938 length = PyLong_Check(lenobj) ?
3939 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3940#endif
3941 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003942 return NULL;
3943
Barry Warsaw53699e91996-12-10 23:23:01 +00003944 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003945 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003946 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003947 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003948 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003949 return NULL;
3950 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003951 Py_INCREF(Py_None);
3952 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003953}
3954#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003955
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003956#ifdef NeXT
3957#define HAVE_PUTENV
3958/* Steve Spicklemire got this putenv from NeXTAnswers */
3959static int
3960putenv(char *newval)
3961{
3962 extern char **environ;
3963
3964 static int firstTime = 1;
3965 char **ep;
3966 char *cp;
3967 int esiz;
3968 char *np;
3969
3970 if (!(np = strchr(newval, '=')))
3971 return 1;
3972 *np = '\0';
3973
3974 /* look it up */
3975 for (ep=environ ; *ep ; ep++)
3976 {
3977 /* this should always be true... */
3978 if (cp = strchr(*ep, '='))
3979 {
3980 *cp = '\0';
3981 if (!strcmp(*ep, newval))
3982 {
3983 /* got it! */
3984 *cp = '=';
3985 break;
3986 }
3987 *cp = '=';
3988 }
3989 else
3990 {
3991 *np = '=';
3992 return 1;
3993 }
3994 }
3995
3996 *np = '=';
3997 if (*ep)
3998 {
3999 /* the string was already there:
4000 just replace it with the new one */
4001 *ep = newval;
4002 return 0;
4003 }
4004
4005 /* expand environ by one */
4006 for (esiz=2, ep=environ ; *ep ; ep++)
4007 esiz++;
4008 if (firstTime)
4009 {
4010 char **epp;
4011 char **newenv;
4012 if (!(newenv = malloc(esiz * sizeof(char *))))
4013 return 1;
4014
4015 for (ep=environ, epp=newenv ; *ep ;)
4016 *epp++ = *ep++;
4017 *epp++ = newval;
4018 *epp = (char *) 0;
4019 environ = newenv;
4020 }
4021 else
4022 {
4023 if (!(environ = realloc(environ, esiz * sizeof(char *))))
4024 return 1;
4025 environ[esiz - 2] = newval;
4026 environ[esiz - 1] = (char *) 0;
4027 firstTime = 0;
4028 }
4029
4030 return 0;
4031}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00004032#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004034
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004035#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004036static char posix_putenv__doc__[] =
4037"putenv(key, value) -> None\n\
4038Change or add an environment variable.";
4039
Fred Drake762e2061999-08-26 17:23:54 +00004040/* Save putenv() parameters as values here, so we can collect them when they
4041 * get re-set with another call for the same key. */
4042static PyObject *posix_putenv_garbage;
4043
Barry Warsaw53699e91996-12-10 23:23:01 +00004044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004045posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004046{
4047 char *s1, *s2;
4048 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004049 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004050 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004051
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004052 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004053 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004054
4055#if defined(PYOS_OS2)
4056 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4057 APIRET rc;
4058
4059 if (strlen(s2) == 0) /* If New Value is an Empty String */
4060 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4061
4062 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4063 if (rc != NO_ERROR)
4064 return os2_error(rc);
4065
4066 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4067 APIRET rc;
4068
4069 if (strlen(s2) == 0) /* If New Value is an Empty String */
4070 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4071
4072 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4073 if (rc != NO_ERROR)
4074 return os2_error(rc);
4075 } else {
4076#endif
4077
Fred Drake762e2061999-08-26 17:23:54 +00004078 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004079 len = strlen(s1) + strlen(s2) + 2;
4080 /* len includes space for a trailing \0; the size arg to
4081 PyString_FromStringAndSize does not count that */
4082 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004083 if (newstr == NULL)
4084 return PyErr_NoMemory();
4085 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004086 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004087 if (putenv(new)) {
4088 posix_error();
4089 return NULL;
4090 }
Fred Drake762e2061999-08-26 17:23:54 +00004091 /* Install the first arg and newstr in posix_putenv_garbage;
4092 * this will cause previous value to be collected. This has to
4093 * happen after the real putenv() call because the old value
4094 * was still accessible until then. */
4095 if (PyDict_SetItem(posix_putenv_garbage,
4096 PyTuple_GET_ITEM(args, 0), newstr)) {
4097 /* really not much we can do; just leak */
4098 PyErr_Clear();
4099 }
4100 else {
4101 Py_DECREF(newstr);
4102 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004103
4104#if defined(PYOS_OS2)
4105 }
4106#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004107 Py_INCREF(Py_None);
4108 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004109}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004110#endif /* putenv */
4111
Guido van Rossumc524d952001-10-19 01:31:59 +00004112#ifdef HAVE_UNSETENV
4113static char posix_unsetenv__doc__[] =
4114"unsetenv(key) -> None\n\
4115Delete an environment variable.";
4116
4117static PyObject *
4118posix_unsetenv(PyObject *self, PyObject *args)
4119{
4120 char *s1;
4121
4122 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4123 return NULL;
4124
4125 unsetenv(s1);
4126
4127 /* Remove the key from posix_putenv_garbage;
4128 * this will cause it to be collected. This has to
4129 * happen after the real unsetenv() call because the
4130 * old value was still accessible until then.
4131 */
4132 if (PyDict_DelItem(posix_putenv_garbage,
4133 PyTuple_GET_ITEM(args, 0))) {
4134 /* really not much we can do; just leak */
4135 PyErr_Clear();
4136 }
4137
4138 Py_INCREF(Py_None);
4139 return Py_None;
4140}
4141#endif /* unsetenv */
4142
Guido van Rossumb6a47161997-09-15 22:54:34 +00004143#ifdef HAVE_STRERROR
4144static char posix_strerror__doc__[] =
4145"strerror(code) -> string\n\
4146Translate an error code to a message string.";
4147
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004148static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004149posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004150{
4151 int code;
4152 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004153 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004154 return NULL;
4155 message = strerror(code);
4156 if (message == NULL) {
4157 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004158 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004159 return NULL;
4160 }
4161 return PyString_FromString(message);
4162}
4163#endif /* strerror */
4164
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004165
Guido van Rossumc9641791998-08-04 15:26:23 +00004166#ifdef HAVE_SYS_WAIT_H
4167
4168#ifdef WIFSTOPPED
4169static char posix_WIFSTOPPED__doc__[] =
4170"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004171Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004172
4173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004174posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004175{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004176#ifdef UNION_WAIT
4177 union wait status;
4178#define status_i (status.w_status)
4179#else
4180 int status;
4181#define status_i status
4182#endif
4183 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004184
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004185 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004186 {
4187 return NULL;
4188 }
4189
4190 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004191#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004192}
4193#endif /* WIFSTOPPED */
4194
4195#ifdef WIFSIGNALED
4196static char posix_WIFSIGNALED__doc__[] =
4197"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004198Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004199
4200static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004201posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004202{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004203#ifdef UNION_WAIT
4204 union wait status;
4205#define status_i (status.w_status)
4206#else
4207 int status;
4208#define status_i status
4209#endif
4210 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004211
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004212 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004213 {
4214 return NULL;
4215 }
4216
4217 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004218#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004219}
4220#endif /* WIFSIGNALED */
4221
4222#ifdef WIFEXITED
4223static char posix_WIFEXITED__doc__[] =
4224"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004225Return true if the process returning 'status' exited using the exit()\n\
4226system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004227
4228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004229posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004230{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004231#ifdef UNION_WAIT
4232 union wait status;
4233#define status_i (status.w_status)
4234#else
4235 int status;
4236#define status_i status
4237#endif
4238 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004239
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004240 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004241 {
4242 return NULL;
4243 }
4244
4245 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004246#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004247}
4248#endif /* WIFEXITED */
4249
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004250#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004251static char posix_WEXITSTATUS__doc__[] =
4252"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004253Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004254
4255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004256posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004257{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004258#ifdef UNION_WAIT
4259 union wait status;
4260#define status_i (status.w_status)
4261#else
4262 int status;
4263#define status_i status
4264#endif
4265 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004266
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004267 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004268 {
4269 return NULL;
4270 }
4271
4272 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004273#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004274}
4275#endif /* WEXITSTATUS */
4276
4277#ifdef WTERMSIG
4278static char posix_WTERMSIG__doc__[] =
4279"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004280Return the signal that terminated the process that provided the 'status'\n\
4281value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004282
4283static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004284posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004285{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004286#ifdef UNION_WAIT
4287 union wait status;
4288#define status_i (status.w_status)
4289#else
4290 int status;
4291#define status_i status
4292#endif
4293 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004294
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004295 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004296 {
4297 return NULL;
4298 }
4299
4300 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004301#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004302}
4303#endif /* WTERMSIG */
4304
4305#ifdef WSTOPSIG
4306static char posix_WSTOPSIG__doc__[] =
4307"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004308Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004309
4310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004311posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004312{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004313#ifdef UNION_WAIT
4314 union wait status;
4315#define status_i (status.w_status)
4316#else
4317 int status;
4318#define status_i status
4319#endif
4320 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004321
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004322 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004323 {
4324 return NULL;
4325 }
4326
4327 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004328#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004329}
4330#endif /* WSTOPSIG */
4331
4332#endif /* HAVE_SYS_WAIT_H */
4333
4334
Guido van Rossum94f6f721999-01-06 18:42:14 +00004335#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004336#ifdef _SCO_DS
4337/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4338 needed definitions in sys/statvfs.h */
4339#define _SVID3
4340#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004341#include <sys/statvfs.h>
4342
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004343static PyObject*
4344_pystatvfs_fromstructstatvfs(struct statvfs st) {
4345 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4346 if (v == NULL)
4347 return NULL;
4348
4349#if !defined(HAVE_LARGEFILE_SUPPORT)
4350 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4351 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4352 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4353 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4354 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4355 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4356 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4357 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4358 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4359 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4360#else
4361 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4362 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4363 PyStructSequence_SET_ITEM(v, 2,
4364 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
4365 PyStructSequence_SET_ITEM(v, 3,
4366 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4367 PyStructSequence_SET_ITEM(v, 4,
4368 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
4369 PyStructSequence_SET_ITEM(v, 5,
4370 PyLong_FromLongLong((LONG_LONG) st.f_files));
4371 PyStructSequence_SET_ITEM(v, 6,
4372 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
4373 PyStructSequence_SET_ITEM(v, 7,
4374 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4375 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4376 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4377#endif
4378
4379 return v;
4380}
4381
Guido van Rossum94f6f721999-01-06 18:42:14 +00004382static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004383"fstatvfs(fd) -> \n\
4384 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004385Perform an fstatvfs system call on the given fd.";
4386
4387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004388posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004389{
4390 int fd, res;
4391 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004392
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004393 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004394 return NULL;
4395 Py_BEGIN_ALLOW_THREADS
4396 res = fstatvfs(fd, &st);
4397 Py_END_ALLOW_THREADS
4398 if (res != 0)
4399 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004400
4401 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004402}
4403#endif /* HAVE_FSTATVFS */
4404
4405
4406#if defined(HAVE_STATVFS)
4407#include <sys/statvfs.h>
4408
4409static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004410"statvfs(path) -> \n\
4411 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004412Perform a statvfs system call on the given path.";
4413
4414static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004415posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004416{
4417 char *path;
4418 int res;
4419 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004420 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004421 return NULL;
4422 Py_BEGIN_ALLOW_THREADS
4423 res = statvfs(path, &st);
4424 Py_END_ALLOW_THREADS
4425 if (res != 0)
4426 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004427
4428 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004429}
4430#endif /* HAVE_STATVFS */
4431
4432
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004433#ifdef HAVE_TEMPNAM
4434static char posix_tempnam__doc__[] = "\
4435tempnam([dir[, prefix]]) -> string\n\
4436Return a unique name for a temporary file.\n\
4437The directory and a short may be specified as strings; they may be omitted\n\
4438or None if not needed.";
4439
4440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004441posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004442{
4443 PyObject *result = NULL;
4444 char *dir = NULL;
4445 char *pfx = NULL;
4446 char *name;
4447
4448 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4449 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004450
4451 if (PyErr_Warn(PyExc_RuntimeWarning,
4452 "tempnam is a potential security risk to your program") < 0)
4453 return NULL;
4454
Fred Drake78b71c22001-07-17 20:37:36 +00004455#ifdef MS_WIN32
4456 name = _tempnam(dir, pfx);
4457#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004458 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004459#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004460 if (name == NULL)
4461 return PyErr_NoMemory();
4462 result = PyString_FromString(name);
4463 free(name);
4464 return result;
4465}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004466#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004467
4468
4469#ifdef HAVE_TMPFILE
4470static char posix_tmpfile__doc__[] = "\
4471tmpfile() -> file object\n\
4472Create a temporary file with no directory entries.";
4473
4474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004475posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004476{
4477 FILE *fp;
4478
4479 if (!PyArg_ParseTuple(args, ":tmpfile"))
4480 return NULL;
4481 fp = tmpfile();
4482 if (fp == NULL)
4483 return posix_error();
4484 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4485}
4486#endif
4487
4488
4489#ifdef HAVE_TMPNAM
4490static char posix_tmpnam__doc__[] = "\
4491tmpnam() -> string\n\
4492Return a unique name for a temporary file.";
4493
4494static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004495posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004496{
4497 char buffer[L_tmpnam];
4498 char *name;
4499
4500 if (!PyArg_ParseTuple(args, ":tmpnam"))
4501 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004502
4503 if (PyErr_Warn(PyExc_RuntimeWarning,
4504 "tmpnam is a potential security risk to your program") < 0)
4505 return NULL;
4506
Greg Wardb48bc172000-03-01 21:51:56 +00004507#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004508 name = tmpnam_r(buffer);
4509#else
4510 name = tmpnam(buffer);
4511#endif
4512 if (name == NULL) {
4513 PyErr_SetObject(PyExc_OSError,
4514 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004515#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004516 "unexpected NULL from tmpnam_r"
4517#else
4518 "unexpected NULL from tmpnam"
4519#endif
4520 ));
4521 return NULL;
4522 }
4523 return PyString_FromString(buffer);
4524}
4525#endif
4526
4527
Fred Drakec9680921999-12-13 16:37:25 +00004528/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4529 * It maps strings representing configuration variable names to
4530 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004531 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004532 * rarely-used constants. There are three separate tables that use
4533 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004534 *
4535 * This code is always included, even if none of the interfaces that
4536 * need it are included. The #if hackery needed to avoid it would be
4537 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004538 */
4539struct constdef {
4540 char *name;
4541 long value;
4542};
4543
Fred Drake12c6e2d1999-12-14 21:25:03 +00004544static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004545conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4546 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004547{
4548 if (PyInt_Check(arg)) {
4549 *valuep = PyInt_AS_LONG(arg);
4550 return 1;
4551 }
4552 if (PyString_Check(arg)) {
4553 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004554 size_t lo = 0;
4555 size_t mid;
4556 size_t hi = tablesize;
4557 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004558 char *confname = PyString_AS_STRING(arg);
4559 while (lo < hi) {
4560 mid = (lo + hi) / 2;
4561 cmp = strcmp(confname, table[mid].name);
4562 if (cmp < 0)
4563 hi = mid;
4564 else if (cmp > 0)
4565 lo = mid + 1;
4566 else {
4567 *valuep = table[mid].value;
4568 return 1;
4569 }
4570 }
4571 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4572 }
4573 else
4574 PyErr_SetString(PyExc_TypeError,
4575 "configuration names must be strings or integers");
4576 return 0;
4577}
4578
4579
4580#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4581static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004582#ifdef _PC_ABI_AIO_XFER_MAX
4583 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4584#endif
4585#ifdef _PC_ABI_ASYNC_IO
4586 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4587#endif
Fred Drakec9680921999-12-13 16:37:25 +00004588#ifdef _PC_ASYNC_IO
4589 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4590#endif
4591#ifdef _PC_CHOWN_RESTRICTED
4592 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4593#endif
4594#ifdef _PC_FILESIZEBITS
4595 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4596#endif
4597#ifdef _PC_LAST
4598 {"PC_LAST", _PC_LAST},
4599#endif
4600#ifdef _PC_LINK_MAX
4601 {"PC_LINK_MAX", _PC_LINK_MAX},
4602#endif
4603#ifdef _PC_MAX_CANON
4604 {"PC_MAX_CANON", _PC_MAX_CANON},
4605#endif
4606#ifdef _PC_MAX_INPUT
4607 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4608#endif
4609#ifdef _PC_NAME_MAX
4610 {"PC_NAME_MAX", _PC_NAME_MAX},
4611#endif
4612#ifdef _PC_NO_TRUNC
4613 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4614#endif
4615#ifdef _PC_PATH_MAX
4616 {"PC_PATH_MAX", _PC_PATH_MAX},
4617#endif
4618#ifdef _PC_PIPE_BUF
4619 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4620#endif
4621#ifdef _PC_PRIO_IO
4622 {"PC_PRIO_IO", _PC_PRIO_IO},
4623#endif
4624#ifdef _PC_SOCK_MAXBUF
4625 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4626#endif
4627#ifdef _PC_SYNC_IO
4628 {"PC_SYNC_IO", _PC_SYNC_IO},
4629#endif
4630#ifdef _PC_VDISABLE
4631 {"PC_VDISABLE", _PC_VDISABLE},
4632#endif
4633};
4634
Fred Drakec9680921999-12-13 16:37:25 +00004635static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004636conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004637{
4638 return conv_confname(arg, valuep, posix_constants_pathconf,
4639 sizeof(posix_constants_pathconf)
4640 / sizeof(struct constdef));
4641}
4642#endif
4643
4644#ifdef HAVE_FPATHCONF
4645static char posix_fpathconf__doc__[] = "\
4646fpathconf(fd, name) -> integer\n\
4647Return the configuration limit name for the file descriptor fd.\n\
4648If there is no limit, return -1.";
4649
4650static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004651posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004652{
4653 PyObject *result = NULL;
4654 int name, fd;
4655
Fred Drake12c6e2d1999-12-14 21:25:03 +00004656 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4657 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004658 long limit;
4659
4660 errno = 0;
4661 limit = fpathconf(fd, name);
4662 if (limit == -1 && errno != 0)
4663 posix_error();
4664 else
4665 result = PyInt_FromLong(limit);
4666 }
4667 return result;
4668}
4669#endif
4670
4671
4672#ifdef HAVE_PATHCONF
4673static char posix_pathconf__doc__[] = "\
4674pathconf(path, name) -> integer\n\
4675Return the configuration limit name for the file or directory path.\n\
4676If there is no limit, return -1.";
4677
4678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004679posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004680{
4681 PyObject *result = NULL;
4682 int name;
4683 char *path;
4684
4685 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4686 conv_path_confname, &name)) {
4687 long limit;
4688
4689 errno = 0;
4690 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004691 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004692 if (errno == EINVAL)
4693 /* could be a path or name problem */
4694 posix_error();
4695 else
4696 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004697 }
Fred Drakec9680921999-12-13 16:37:25 +00004698 else
4699 result = PyInt_FromLong(limit);
4700 }
4701 return result;
4702}
4703#endif
4704
4705#ifdef HAVE_CONFSTR
4706static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004707#ifdef _CS_ARCHITECTURE
4708 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4709#endif
4710#ifdef _CS_HOSTNAME
4711 {"CS_HOSTNAME", _CS_HOSTNAME},
4712#endif
4713#ifdef _CS_HW_PROVIDER
4714 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4715#endif
4716#ifdef _CS_HW_SERIAL
4717 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4718#endif
4719#ifdef _CS_INITTAB_NAME
4720 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4721#endif
Fred Drakec9680921999-12-13 16:37:25 +00004722#ifdef _CS_LFS64_CFLAGS
4723 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4724#endif
4725#ifdef _CS_LFS64_LDFLAGS
4726 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4727#endif
4728#ifdef _CS_LFS64_LIBS
4729 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4730#endif
4731#ifdef _CS_LFS64_LINTFLAGS
4732 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4733#endif
4734#ifdef _CS_LFS_CFLAGS
4735 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4736#endif
4737#ifdef _CS_LFS_LDFLAGS
4738 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4739#endif
4740#ifdef _CS_LFS_LIBS
4741 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4742#endif
4743#ifdef _CS_LFS_LINTFLAGS
4744 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4745#endif
Fred Draked86ed291999-12-15 15:34:33 +00004746#ifdef _CS_MACHINE
4747 {"CS_MACHINE", _CS_MACHINE},
4748#endif
Fred Drakec9680921999-12-13 16:37:25 +00004749#ifdef _CS_PATH
4750 {"CS_PATH", _CS_PATH},
4751#endif
Fred Draked86ed291999-12-15 15:34:33 +00004752#ifdef _CS_RELEASE
4753 {"CS_RELEASE", _CS_RELEASE},
4754#endif
4755#ifdef _CS_SRPC_DOMAIN
4756 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4757#endif
4758#ifdef _CS_SYSNAME
4759 {"CS_SYSNAME", _CS_SYSNAME},
4760#endif
4761#ifdef _CS_VERSION
4762 {"CS_VERSION", _CS_VERSION},
4763#endif
Fred Drakec9680921999-12-13 16:37:25 +00004764#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4765 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4766#endif
4767#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4768 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4769#endif
4770#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4771 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4772#endif
4773#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4774 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4775#endif
4776#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4777 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4778#endif
4779#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4780 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4781#endif
4782#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4783 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4784#endif
4785#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4786 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4787#endif
4788#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4789 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4790#endif
4791#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4792 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4793#endif
4794#ifdef _CS_XBS5_LP64_OFF64_LIBS
4795 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4796#endif
4797#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4798 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4799#endif
4800#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4801 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4802#endif
4803#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4804 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4805#endif
4806#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4807 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4808#endif
4809#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4810 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4811#endif
Fred Draked86ed291999-12-15 15:34:33 +00004812#ifdef _MIPS_CS_AVAIL_PROCESSORS
4813 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4814#endif
4815#ifdef _MIPS_CS_BASE
4816 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4817#endif
4818#ifdef _MIPS_CS_HOSTID
4819 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4820#endif
4821#ifdef _MIPS_CS_HW_NAME
4822 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4823#endif
4824#ifdef _MIPS_CS_NUM_PROCESSORS
4825 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4826#endif
4827#ifdef _MIPS_CS_OSREL_MAJ
4828 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4829#endif
4830#ifdef _MIPS_CS_OSREL_MIN
4831 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4832#endif
4833#ifdef _MIPS_CS_OSREL_PATCH
4834 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4835#endif
4836#ifdef _MIPS_CS_OS_NAME
4837 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4838#endif
4839#ifdef _MIPS_CS_OS_PROVIDER
4840 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4841#endif
4842#ifdef _MIPS_CS_PROCESSORS
4843 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4844#endif
4845#ifdef _MIPS_CS_SERIAL
4846 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4847#endif
4848#ifdef _MIPS_CS_VENDOR
4849 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4850#endif
Fred Drakec9680921999-12-13 16:37:25 +00004851};
4852
4853static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004854conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004855{
4856 return conv_confname(arg, valuep, posix_constants_confstr,
4857 sizeof(posix_constants_confstr)
4858 / sizeof(struct constdef));
4859}
4860
4861static char posix_confstr__doc__[] = "\
4862confstr(name) -> string\n\
4863Return a string-valued system configuration variable.";
4864
4865static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004866posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004867{
4868 PyObject *result = NULL;
4869 int name;
4870 char buffer[64];
4871
4872 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4873 int len = confstr(name, buffer, sizeof(buffer));
4874
Fred Drakec9680921999-12-13 16:37:25 +00004875 errno = 0;
4876 if (len == 0) {
4877 if (errno != 0)
4878 posix_error();
4879 else
4880 result = PyString_FromString("");
4881 }
4882 else {
4883 if (len >= sizeof(buffer)) {
4884 result = PyString_FromStringAndSize(NULL, len);
4885 if (result != NULL)
4886 confstr(name, PyString_AS_STRING(result), len+1);
4887 }
4888 else
4889 result = PyString_FromString(buffer);
4890 }
4891 }
4892 return result;
4893}
4894#endif
4895
4896
4897#ifdef HAVE_SYSCONF
4898static struct constdef posix_constants_sysconf[] = {
4899#ifdef _SC_2_CHAR_TERM
4900 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4901#endif
4902#ifdef _SC_2_C_BIND
4903 {"SC_2_C_BIND", _SC_2_C_BIND},
4904#endif
4905#ifdef _SC_2_C_DEV
4906 {"SC_2_C_DEV", _SC_2_C_DEV},
4907#endif
4908#ifdef _SC_2_C_VERSION
4909 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4910#endif
4911#ifdef _SC_2_FORT_DEV
4912 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4913#endif
4914#ifdef _SC_2_FORT_RUN
4915 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4916#endif
4917#ifdef _SC_2_LOCALEDEF
4918 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4919#endif
4920#ifdef _SC_2_SW_DEV
4921 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4922#endif
4923#ifdef _SC_2_UPE
4924 {"SC_2_UPE", _SC_2_UPE},
4925#endif
4926#ifdef _SC_2_VERSION
4927 {"SC_2_VERSION", _SC_2_VERSION},
4928#endif
Fred Draked86ed291999-12-15 15:34:33 +00004929#ifdef _SC_ABI_ASYNCHRONOUS_IO
4930 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4931#endif
4932#ifdef _SC_ACL
4933 {"SC_ACL", _SC_ACL},
4934#endif
Fred Drakec9680921999-12-13 16:37:25 +00004935#ifdef _SC_AIO_LISTIO_MAX
4936 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4937#endif
Fred Drakec9680921999-12-13 16:37:25 +00004938#ifdef _SC_AIO_MAX
4939 {"SC_AIO_MAX", _SC_AIO_MAX},
4940#endif
4941#ifdef _SC_AIO_PRIO_DELTA_MAX
4942 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4943#endif
4944#ifdef _SC_ARG_MAX
4945 {"SC_ARG_MAX", _SC_ARG_MAX},
4946#endif
4947#ifdef _SC_ASYNCHRONOUS_IO
4948 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4949#endif
4950#ifdef _SC_ATEXIT_MAX
4951 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4952#endif
Fred Draked86ed291999-12-15 15:34:33 +00004953#ifdef _SC_AUDIT
4954 {"SC_AUDIT", _SC_AUDIT},
4955#endif
Fred Drakec9680921999-12-13 16:37:25 +00004956#ifdef _SC_AVPHYS_PAGES
4957 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4958#endif
4959#ifdef _SC_BC_BASE_MAX
4960 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4961#endif
4962#ifdef _SC_BC_DIM_MAX
4963 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4964#endif
4965#ifdef _SC_BC_SCALE_MAX
4966 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4967#endif
4968#ifdef _SC_BC_STRING_MAX
4969 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4970#endif
Fred Draked86ed291999-12-15 15:34:33 +00004971#ifdef _SC_CAP
4972 {"SC_CAP", _SC_CAP},
4973#endif
Fred Drakec9680921999-12-13 16:37:25 +00004974#ifdef _SC_CHARCLASS_NAME_MAX
4975 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4976#endif
4977#ifdef _SC_CHAR_BIT
4978 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4979#endif
4980#ifdef _SC_CHAR_MAX
4981 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4982#endif
4983#ifdef _SC_CHAR_MIN
4984 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4985#endif
4986#ifdef _SC_CHILD_MAX
4987 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4988#endif
4989#ifdef _SC_CLK_TCK
4990 {"SC_CLK_TCK", _SC_CLK_TCK},
4991#endif
4992#ifdef _SC_COHER_BLKSZ
4993 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4994#endif
4995#ifdef _SC_COLL_WEIGHTS_MAX
4996 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4997#endif
4998#ifdef _SC_DCACHE_ASSOC
4999 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5000#endif
5001#ifdef _SC_DCACHE_BLKSZ
5002 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5003#endif
5004#ifdef _SC_DCACHE_LINESZ
5005 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5006#endif
5007#ifdef _SC_DCACHE_SZ
5008 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5009#endif
5010#ifdef _SC_DCACHE_TBLKSZ
5011 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5012#endif
5013#ifdef _SC_DELAYTIMER_MAX
5014 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5015#endif
5016#ifdef _SC_EQUIV_CLASS_MAX
5017 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5018#endif
5019#ifdef _SC_EXPR_NEST_MAX
5020 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5021#endif
5022#ifdef _SC_FSYNC
5023 {"SC_FSYNC", _SC_FSYNC},
5024#endif
5025#ifdef _SC_GETGR_R_SIZE_MAX
5026 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5027#endif
5028#ifdef _SC_GETPW_R_SIZE_MAX
5029 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5030#endif
5031#ifdef _SC_ICACHE_ASSOC
5032 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5033#endif
5034#ifdef _SC_ICACHE_BLKSZ
5035 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5036#endif
5037#ifdef _SC_ICACHE_LINESZ
5038 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5039#endif
5040#ifdef _SC_ICACHE_SZ
5041 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5042#endif
Fred Draked86ed291999-12-15 15:34:33 +00005043#ifdef _SC_INF
5044 {"SC_INF", _SC_INF},
5045#endif
Fred Drakec9680921999-12-13 16:37:25 +00005046#ifdef _SC_INT_MAX
5047 {"SC_INT_MAX", _SC_INT_MAX},
5048#endif
5049#ifdef _SC_INT_MIN
5050 {"SC_INT_MIN", _SC_INT_MIN},
5051#endif
5052#ifdef _SC_IOV_MAX
5053 {"SC_IOV_MAX", _SC_IOV_MAX},
5054#endif
Fred Draked86ed291999-12-15 15:34:33 +00005055#ifdef _SC_IP_SECOPTS
5056 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5057#endif
Fred Drakec9680921999-12-13 16:37:25 +00005058#ifdef _SC_JOB_CONTROL
5059 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5060#endif
Fred Draked86ed291999-12-15 15:34:33 +00005061#ifdef _SC_KERN_POINTERS
5062 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5063#endif
5064#ifdef _SC_KERN_SIM
5065 {"SC_KERN_SIM", _SC_KERN_SIM},
5066#endif
Fred Drakec9680921999-12-13 16:37:25 +00005067#ifdef _SC_LINE_MAX
5068 {"SC_LINE_MAX", _SC_LINE_MAX},
5069#endif
5070#ifdef _SC_LOGIN_NAME_MAX
5071 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5072#endif
5073#ifdef _SC_LOGNAME_MAX
5074 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5075#endif
5076#ifdef _SC_LONG_BIT
5077 {"SC_LONG_BIT", _SC_LONG_BIT},
5078#endif
Fred Draked86ed291999-12-15 15:34:33 +00005079#ifdef _SC_MAC
5080 {"SC_MAC", _SC_MAC},
5081#endif
Fred Drakec9680921999-12-13 16:37:25 +00005082#ifdef _SC_MAPPED_FILES
5083 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5084#endif
5085#ifdef _SC_MAXPID
5086 {"SC_MAXPID", _SC_MAXPID},
5087#endif
5088#ifdef _SC_MB_LEN_MAX
5089 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5090#endif
5091#ifdef _SC_MEMLOCK
5092 {"SC_MEMLOCK", _SC_MEMLOCK},
5093#endif
5094#ifdef _SC_MEMLOCK_RANGE
5095 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5096#endif
5097#ifdef _SC_MEMORY_PROTECTION
5098 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5099#endif
5100#ifdef _SC_MESSAGE_PASSING
5101 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5102#endif
Fred Draked86ed291999-12-15 15:34:33 +00005103#ifdef _SC_MMAP_FIXED_ALIGNMENT
5104 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5105#endif
Fred Drakec9680921999-12-13 16:37:25 +00005106#ifdef _SC_MQ_OPEN_MAX
5107 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5108#endif
5109#ifdef _SC_MQ_PRIO_MAX
5110 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5111#endif
Fred Draked86ed291999-12-15 15:34:33 +00005112#ifdef _SC_NACLS_MAX
5113 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5114#endif
Fred Drakec9680921999-12-13 16:37:25 +00005115#ifdef _SC_NGROUPS_MAX
5116 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5117#endif
5118#ifdef _SC_NL_ARGMAX
5119 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5120#endif
5121#ifdef _SC_NL_LANGMAX
5122 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5123#endif
5124#ifdef _SC_NL_MSGMAX
5125 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5126#endif
5127#ifdef _SC_NL_NMAX
5128 {"SC_NL_NMAX", _SC_NL_NMAX},
5129#endif
5130#ifdef _SC_NL_SETMAX
5131 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5132#endif
5133#ifdef _SC_NL_TEXTMAX
5134 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5135#endif
5136#ifdef _SC_NPROCESSORS_CONF
5137 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5138#endif
5139#ifdef _SC_NPROCESSORS_ONLN
5140 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5141#endif
Fred Draked86ed291999-12-15 15:34:33 +00005142#ifdef _SC_NPROC_CONF
5143 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5144#endif
5145#ifdef _SC_NPROC_ONLN
5146 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5147#endif
Fred Drakec9680921999-12-13 16:37:25 +00005148#ifdef _SC_NZERO
5149 {"SC_NZERO", _SC_NZERO},
5150#endif
5151#ifdef _SC_OPEN_MAX
5152 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5153#endif
5154#ifdef _SC_PAGESIZE
5155 {"SC_PAGESIZE", _SC_PAGESIZE},
5156#endif
5157#ifdef _SC_PAGE_SIZE
5158 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5159#endif
5160#ifdef _SC_PASS_MAX
5161 {"SC_PASS_MAX", _SC_PASS_MAX},
5162#endif
5163#ifdef _SC_PHYS_PAGES
5164 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5165#endif
5166#ifdef _SC_PII
5167 {"SC_PII", _SC_PII},
5168#endif
5169#ifdef _SC_PII_INTERNET
5170 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5171#endif
5172#ifdef _SC_PII_INTERNET_DGRAM
5173 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5174#endif
5175#ifdef _SC_PII_INTERNET_STREAM
5176 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5177#endif
5178#ifdef _SC_PII_OSI
5179 {"SC_PII_OSI", _SC_PII_OSI},
5180#endif
5181#ifdef _SC_PII_OSI_CLTS
5182 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5183#endif
5184#ifdef _SC_PII_OSI_COTS
5185 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5186#endif
5187#ifdef _SC_PII_OSI_M
5188 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5189#endif
5190#ifdef _SC_PII_SOCKET
5191 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5192#endif
5193#ifdef _SC_PII_XTI
5194 {"SC_PII_XTI", _SC_PII_XTI},
5195#endif
5196#ifdef _SC_POLL
5197 {"SC_POLL", _SC_POLL},
5198#endif
5199#ifdef _SC_PRIORITIZED_IO
5200 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5201#endif
5202#ifdef _SC_PRIORITY_SCHEDULING
5203 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5204#endif
5205#ifdef _SC_REALTIME_SIGNALS
5206 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5207#endif
5208#ifdef _SC_RE_DUP_MAX
5209 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5210#endif
5211#ifdef _SC_RTSIG_MAX
5212 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5213#endif
5214#ifdef _SC_SAVED_IDS
5215 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5216#endif
5217#ifdef _SC_SCHAR_MAX
5218 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5219#endif
5220#ifdef _SC_SCHAR_MIN
5221 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5222#endif
5223#ifdef _SC_SELECT
5224 {"SC_SELECT", _SC_SELECT},
5225#endif
5226#ifdef _SC_SEMAPHORES
5227 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5228#endif
5229#ifdef _SC_SEM_NSEMS_MAX
5230 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5231#endif
5232#ifdef _SC_SEM_VALUE_MAX
5233 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5234#endif
5235#ifdef _SC_SHARED_MEMORY_OBJECTS
5236 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5237#endif
5238#ifdef _SC_SHRT_MAX
5239 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5240#endif
5241#ifdef _SC_SHRT_MIN
5242 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5243#endif
5244#ifdef _SC_SIGQUEUE_MAX
5245 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5246#endif
5247#ifdef _SC_SIGRT_MAX
5248 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5249#endif
5250#ifdef _SC_SIGRT_MIN
5251 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5252#endif
Fred Draked86ed291999-12-15 15:34:33 +00005253#ifdef _SC_SOFTPOWER
5254 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5255#endif
Fred Drakec9680921999-12-13 16:37:25 +00005256#ifdef _SC_SPLIT_CACHE
5257 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5258#endif
5259#ifdef _SC_SSIZE_MAX
5260 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5261#endif
5262#ifdef _SC_STACK_PROT
5263 {"SC_STACK_PROT", _SC_STACK_PROT},
5264#endif
5265#ifdef _SC_STREAM_MAX
5266 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5267#endif
5268#ifdef _SC_SYNCHRONIZED_IO
5269 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5270#endif
5271#ifdef _SC_THREADS
5272 {"SC_THREADS", _SC_THREADS},
5273#endif
5274#ifdef _SC_THREAD_ATTR_STACKADDR
5275 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5276#endif
5277#ifdef _SC_THREAD_ATTR_STACKSIZE
5278 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5279#endif
5280#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5281 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5282#endif
5283#ifdef _SC_THREAD_KEYS_MAX
5284 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5285#endif
5286#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5287 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5288#endif
5289#ifdef _SC_THREAD_PRIO_INHERIT
5290 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5291#endif
5292#ifdef _SC_THREAD_PRIO_PROTECT
5293 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5294#endif
5295#ifdef _SC_THREAD_PROCESS_SHARED
5296 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5297#endif
5298#ifdef _SC_THREAD_SAFE_FUNCTIONS
5299 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5300#endif
5301#ifdef _SC_THREAD_STACK_MIN
5302 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5303#endif
5304#ifdef _SC_THREAD_THREADS_MAX
5305 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5306#endif
5307#ifdef _SC_TIMERS
5308 {"SC_TIMERS", _SC_TIMERS},
5309#endif
5310#ifdef _SC_TIMER_MAX
5311 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5312#endif
5313#ifdef _SC_TTY_NAME_MAX
5314 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5315#endif
5316#ifdef _SC_TZNAME_MAX
5317 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5318#endif
5319#ifdef _SC_T_IOV_MAX
5320 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5321#endif
5322#ifdef _SC_UCHAR_MAX
5323 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5324#endif
5325#ifdef _SC_UINT_MAX
5326 {"SC_UINT_MAX", _SC_UINT_MAX},
5327#endif
5328#ifdef _SC_UIO_MAXIOV
5329 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5330#endif
5331#ifdef _SC_ULONG_MAX
5332 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5333#endif
5334#ifdef _SC_USHRT_MAX
5335 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5336#endif
5337#ifdef _SC_VERSION
5338 {"SC_VERSION", _SC_VERSION},
5339#endif
5340#ifdef _SC_WORD_BIT
5341 {"SC_WORD_BIT", _SC_WORD_BIT},
5342#endif
5343#ifdef _SC_XBS5_ILP32_OFF32
5344 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5345#endif
5346#ifdef _SC_XBS5_ILP32_OFFBIG
5347 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5348#endif
5349#ifdef _SC_XBS5_LP64_OFF64
5350 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5351#endif
5352#ifdef _SC_XBS5_LPBIG_OFFBIG
5353 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5354#endif
5355#ifdef _SC_XOPEN_CRYPT
5356 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5357#endif
5358#ifdef _SC_XOPEN_ENH_I18N
5359 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5360#endif
5361#ifdef _SC_XOPEN_LEGACY
5362 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5363#endif
5364#ifdef _SC_XOPEN_REALTIME
5365 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5366#endif
5367#ifdef _SC_XOPEN_REALTIME_THREADS
5368 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5369#endif
5370#ifdef _SC_XOPEN_SHM
5371 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5372#endif
5373#ifdef _SC_XOPEN_UNIX
5374 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5375#endif
5376#ifdef _SC_XOPEN_VERSION
5377 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5378#endif
5379#ifdef _SC_XOPEN_XCU_VERSION
5380 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5381#endif
5382#ifdef _SC_XOPEN_XPG2
5383 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5384#endif
5385#ifdef _SC_XOPEN_XPG3
5386 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5387#endif
5388#ifdef _SC_XOPEN_XPG4
5389 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5390#endif
5391};
5392
5393static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005394conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005395{
5396 return conv_confname(arg, valuep, posix_constants_sysconf,
5397 sizeof(posix_constants_sysconf)
5398 / sizeof(struct constdef));
5399}
5400
5401static char posix_sysconf__doc__[] = "\
5402sysconf(name) -> integer\n\
5403Return an integer-valued system configuration variable.";
5404
5405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005406posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005407{
5408 PyObject *result = NULL;
5409 int name;
5410
5411 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5412 int value;
5413
5414 errno = 0;
5415 value = sysconf(name);
5416 if (value == -1 && errno != 0)
5417 posix_error();
5418 else
5419 result = PyInt_FromLong(value);
5420 }
5421 return result;
5422}
5423#endif
5424
5425
Fred Drakebec628d1999-12-15 18:31:10 +00005426/* This code is used to ensure that the tables of configuration value names
5427 * are in sorted order as required by conv_confname(), and also to build the
5428 * the exported dictionaries that are used to publish information about the
5429 * names available on the host platform.
5430 *
5431 * Sorting the table at runtime ensures that the table is properly ordered
5432 * when used, even for platforms we're not able to test on. It also makes
5433 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005434 */
Fred Drakebec628d1999-12-15 18:31:10 +00005435
5436static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005437cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005438{
5439 const struct constdef *c1 =
5440 (const struct constdef *) v1;
5441 const struct constdef *c2 =
5442 (const struct constdef *) v2;
5443
5444 return strcmp(c1->name, c2->name);
5445}
5446
5447static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005448setup_confname_table(struct constdef *table, size_t tablesize,
5449 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005450{
Fred Drakebec628d1999-12-15 18:31:10 +00005451 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005452 size_t i;
5453 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005454
5455 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5456 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005457 if (d == NULL)
5458 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005459
Barry Warsaw3155db32000-04-13 15:20:40 +00005460 for (i=0; i < tablesize; ++i) {
5461 PyObject *o = PyInt_FromLong(table[i].value);
5462 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5463 Py_XDECREF(o);
5464 Py_DECREF(d);
5465 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005466 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005467 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005468 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005469 status = PyDict_SetItemString(moddict, tablename, d);
5470 Py_DECREF(d);
5471 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005472}
5473
Fred Drakebec628d1999-12-15 18:31:10 +00005474/* Return -1 on failure, 0 on success. */
5475static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005476setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005477{
5478#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005479 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005480 sizeof(posix_constants_pathconf)
5481 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005482 "pathconf_names", moddict))
5483 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005484#endif
5485#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005486 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005487 sizeof(posix_constants_confstr)
5488 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005489 "confstr_names", moddict))
5490 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005491#endif
5492#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005493 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005494 sizeof(posix_constants_sysconf)
5495 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005496 "sysconf_names", moddict))
5497 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005498#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005499 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005500}
Fred Draked86ed291999-12-15 15:34:33 +00005501
5502
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005503static char posix_abort__doc__[] = "\
5504abort() -> does not return!\n\
5505Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5506in the hardest way possible on the hosting operating system.";
5507
5508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005509posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005510{
5511 if (!PyArg_ParseTuple(args, ":abort"))
5512 return NULL;
5513 abort();
5514 /*NOTREACHED*/
5515 Py_FatalError("abort() called from Python code didn't abort!");
5516 return NULL;
5517}
Fred Drakebec628d1999-12-15 18:31:10 +00005518
Tim Petersf58a7aa2000-09-22 10:05:54 +00005519#ifdef MS_WIN32
5520static char win32_startfile__doc__[] = "\
5521startfile(filepath) - Start a file with its associated application.\n\
5522\n\
5523This acts like double-clicking the file in Explorer, or giving the file\n\
5524name as an argument to the DOS \"start\" command: the file is opened\n\
5525with whatever application (if any) its extension is associated.\n\
5526\n\
5527startfile returns as soon as the associated application is launched.\n\
5528There is no option to wait for the application to close, and no way\n\
5529to retrieve the application's exit status.\n\
5530\n\
5531The filepath is relative to the current directory. If you want to use\n\
5532an absolute path, make sure the first character is not a slash (\"/\");\n\
5533the underlying Win32 ShellExecute function doesn't work if it is.";
5534
5535static PyObject *
5536win32_startfile(PyObject *self, PyObject *args)
5537{
5538 char *filepath;
5539 HINSTANCE rc;
5540 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5541 return NULL;
5542 Py_BEGIN_ALLOW_THREADS
5543 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5544 Py_END_ALLOW_THREADS
5545 if (rc <= (HINSTANCE)32)
5546 return win32_error("startfile", filepath);
5547 Py_INCREF(Py_None);
5548 return Py_None;
5549}
5550#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005551
5552static PyMethodDef posix_methods[] = {
5553 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5554#ifdef HAVE_TTYNAME
5555 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5556#endif
5557 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5558 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005559#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005560 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005561#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005562#ifdef HAVE_CHROOT
5563 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5564#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005565#ifdef HAVE_CTERMID
5566 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5567#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005568#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005569 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005570#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005571#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005572 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005573#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005574 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5575 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5576 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005577#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005578 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005579#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005580#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005581 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005582#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005583 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5584 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5585 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005586#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005587 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005588#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005589#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005590 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005591#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005592 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005593#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005594 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005595#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005596 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5597 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5598 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005599#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005600 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005601#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005602 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005603#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005604 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5605 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005606#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005607#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005608 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5609 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005610#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005611#ifdef HAVE_FORK1
5612 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5613#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005614#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005615 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005616#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005617#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005618 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005619#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005620#ifdef HAVE_FORKPTY
5621 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5622#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005623#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005624 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005625#endif /* HAVE_GETEGID */
5626#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005627 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005628#endif /* HAVE_GETEUID */
5629#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005630 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005631#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005632#ifdef HAVE_GETGROUPS
5633 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5634#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005635 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005636#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005637 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005638#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005639#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005640 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005641#endif /* HAVE_GETPPID */
5642#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005643 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005644#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005645#ifdef HAVE_GETLOGIN
5646 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5647#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005648#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005649 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005650#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005651#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005652 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005653#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005654#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005655 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005656#ifdef MS_WIN32
5657 {"popen2", win32_popen2, METH_VARARGS},
5658 {"popen3", win32_popen3, METH_VARARGS},
5659 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005660 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005661#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005662#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005663#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005664 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005665#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005666#ifdef HAVE_SETEUID
5667 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5668#endif /* HAVE_SETEUID */
5669#ifdef HAVE_SETEGID
5670 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5671#endif /* HAVE_SETEGID */
5672#ifdef HAVE_SETREUID
5673 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5674#endif /* HAVE_SETREUID */
5675#ifdef HAVE_SETREGID
5676 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5677#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005678#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005679 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005680#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005681#ifdef HAVE_SETGROUPS
5682 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5683#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005684#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005685 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005686#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005687#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005688 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005689#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005690#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005691 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005692#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005693#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005694 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005695#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005696#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005697 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005698#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005699#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005700 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005701#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005702#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005703 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005704#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005705 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5706 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5707 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5708 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5709 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5710 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5711 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5712 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5713 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005714 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005715#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005716 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005717#endif
5718#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005719 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005720#endif
5721#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005722 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005723#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005724#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005725 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005726#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005727#ifdef HAVE_UNSETENV
5728 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
5729#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005730#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005731 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005732#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005733#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005734 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005735#endif
5736#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005737 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005738#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005739#ifdef HAVE_SYS_WAIT_H
5740#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005741 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005742#endif /* WIFSTOPPED */
5743#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005744 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005745#endif /* WIFSIGNALED */
5746#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005747 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005748#endif /* WIFEXITED */
5749#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005750 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005751#endif /* WEXITSTATUS */
5752#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005753 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005754#endif /* WTERMSIG */
5755#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005756 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005757#endif /* WSTOPSIG */
5758#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005759#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005760 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005761#endif
5762#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005763 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005764#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005765#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005766 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5767#endif
5768#ifdef HAVE_TEMPNAM
5769 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5770#endif
5771#ifdef HAVE_TMPNAM
5772 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5773#endif
Fred Drakec9680921999-12-13 16:37:25 +00005774#ifdef HAVE_CONFSTR
5775 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5776#endif
5777#ifdef HAVE_SYSCONF
5778 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5779#endif
5780#ifdef HAVE_FPATHCONF
5781 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5782#endif
5783#ifdef HAVE_PATHCONF
5784 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5785#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005786 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005787#ifdef MS_WIN32
5788 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5789#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005790 {NULL, NULL} /* Sentinel */
5791};
5792
5793
Barry Warsaw4a342091996-12-19 23:50:02 +00005794static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005795ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005796{
5797 PyObject* v = PyInt_FromLong(value);
5798 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5799 return -1; /* triggers fatal error */
5800
5801 Py_DECREF(v);
5802 return 0;
5803}
5804
Guido van Rossumd48f2521997-12-05 22:19:34 +00005805#if defined(PYOS_OS2)
5806/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5807static int insertvalues(PyObject *d)
5808{
5809 APIRET rc;
5810 ULONG values[QSV_MAX+1];
5811 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00005812 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00005813
5814 Py_BEGIN_ALLOW_THREADS
5815 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5816 Py_END_ALLOW_THREADS
5817
5818 if (rc != NO_ERROR) {
5819 os2_error(rc);
5820 return -1;
5821 }
5822
5823 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5824 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5825 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5826 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5827 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5828 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5829 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5830
5831 switch (values[QSV_VERSION_MINOR]) {
5832 case 0: ver = "2.00"; break;
5833 case 10: ver = "2.10"; break;
5834 case 11: ver = "2.11"; break;
5835 case 30: ver = "3.00"; break;
5836 case 40: ver = "4.00"; break;
5837 case 50: ver = "5.00"; break;
5838 default:
Tim Peters885d4572001-11-28 20:27:42 +00005839 PyOS_snprintf(tmp, sizeof(tmp),
5840 "%d-%d", values[QSV_VERSION_MAJOR],
5841 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005842 ver = &tmp[0];
5843 }
5844
5845 /* Add Indicator of the Version of the Operating System */
5846 v = PyString_FromString(ver);
5847 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5848 return -1;
5849 Py_DECREF(v);
5850
5851 /* Add Indicator of Which Drive was Used to Boot the System */
5852 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5853 tmp[1] = ':';
5854 tmp[2] = '\0';
5855
5856 v = PyString_FromString(tmp);
5857 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5858 return -1;
5859 Py_DECREF(v);
5860
5861 return 0;
5862}
5863#endif
5864
Barry Warsaw4a342091996-12-19 23:50:02 +00005865static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005866all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005867{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005868#ifdef F_OK
5869 if (ins(d, "F_OK", (long)F_OK)) return -1;
5870#endif
5871#ifdef R_OK
5872 if (ins(d, "R_OK", (long)R_OK)) return -1;
5873#endif
5874#ifdef W_OK
5875 if (ins(d, "W_OK", (long)W_OK)) return -1;
5876#endif
5877#ifdef X_OK
5878 if (ins(d, "X_OK", (long)X_OK)) return -1;
5879#endif
Fred Drakec9680921999-12-13 16:37:25 +00005880#ifdef NGROUPS_MAX
5881 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5882#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005883#ifdef TMP_MAX
5884 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5885#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005886#ifdef WNOHANG
5887 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5888#endif
5889#ifdef O_RDONLY
5890 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5891#endif
5892#ifdef O_WRONLY
5893 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5894#endif
5895#ifdef O_RDWR
5896 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5897#endif
5898#ifdef O_NDELAY
5899 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5900#endif
5901#ifdef O_NONBLOCK
5902 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5903#endif
5904#ifdef O_APPEND
5905 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5906#endif
5907#ifdef O_DSYNC
5908 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5909#endif
5910#ifdef O_RSYNC
5911 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5912#endif
5913#ifdef O_SYNC
5914 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5915#endif
5916#ifdef O_NOCTTY
5917 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5918#endif
5919#ifdef O_CREAT
5920 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5921#endif
5922#ifdef O_EXCL
5923 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5924#endif
5925#ifdef O_TRUNC
5926 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5927#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005928#ifdef O_BINARY
5929 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5930#endif
5931#ifdef O_TEXT
5932 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5933#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005934#ifdef O_LARGEFILE
5935 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
5936#endif
5937
5938/* GNU extensions. */
5939#ifdef O_DIRECT
5940 /* Direct disk access. */
5941 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
5942#endif
5943#ifdef O_DIRECTORY
5944 /* Must be a directory. */
5945 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
5946#endif
5947#ifdef O_NOFOLLOW
5948 /* Do not follow links. */
5949 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
5950#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005951
Guido van Rossum246bc171999-02-01 23:54:31 +00005952#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005953 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5954 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5955 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5956 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5957 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005958#endif
5959
Guido van Rossumd48f2521997-12-05 22:19:34 +00005960#if defined(PYOS_OS2)
5961 if (insertvalues(d)) return -1;
5962#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005963 return 0;
5964}
5965
5966
Tim Peters58e0a8c2001-05-14 22:32:33 +00005967#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005968#define INITFUNC initnt
5969#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005970
5971#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005972#define INITFUNC initos2
5973#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005974
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005975#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005976#define INITFUNC initposix
5977#define MODNAME "posix"
5978#endif
5979
Guido van Rossum3886bb61998-12-04 18:50:17 +00005980DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005981INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005982{
Barry Warsaw53699e91996-12-10 23:23:01 +00005983 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005984
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005985 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005986 posix_methods,
5987 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005988 (PyObject *)NULL,
5989 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005990 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005991
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005992 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005993 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005994 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005995 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005996 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005997
Barry Warsaw4a342091996-12-19 23:50:02 +00005998 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005999 return;
6000
Fred Drakebec628d1999-12-15 18:31:10 +00006001 if (setup_confname_tables(d))
6002 return;
6003
Barry Warsawca74da41999-02-09 19:31:45 +00006004 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006005
Guido van Rossumb3d39562000-01-31 18:41:26 +00006006#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006007 if (posix_putenv_garbage == NULL)
6008 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006009#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006010
Guido van Rossum14648392001-12-08 18:02:58 +00006011 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006012 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
6013 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
6014
Guido van Rossum14648392001-12-08 18:02:58 +00006015 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006016 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Guido van Rossumbb2501f2001-12-27 16:23:28 +00006017 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006018}