blob: bb557626baed5bd3223c730a6f61627be1236985 [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;
Mark Hammondef8b6542001-05-13 08:04:26 +0000682 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000683 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000684
685#ifdef MS_WIN32
686 int pathlen;
687 char pathcopy[MAX_PATH];
688#endif /* MS_WIN32 */
689
Mark Hammondef8b6542001-05-13 08:04:26 +0000690 if (!PyArg_ParseTuple(args, format,
691 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000692 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000693
694#ifdef MS_WIN32
695 pathlen = strlen(path);
696 /* the library call can blow up if the file name is too long! */
697 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000698 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000699 errno = ENAMETOOLONG;
700 return posix_error();
701 }
702
703 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000704 /* exception for specific or current drive root */
705 if (!((pathlen == 1) ||
706 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000707 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000708 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000709 {
710 strncpy(pathcopy, path, pathlen);
711 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
712 path = pathcopy;
713 }
714 }
715#endif /* MS_WIN32 */
716
Barry Warsaw53699e91996-12-10 23:23:01 +0000717 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000718 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000719 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000720 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000721 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000722
Mark Hammondef8b6542001-05-13 08:04:26 +0000723 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000724 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725}
726
727
728/* POSIX methods */
729
Guido van Rossum94f6f721999-01-06 18:42:14 +0000730static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000731"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000732Test for access to a file.";
733
734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000735posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000736{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000737 char *path;
738 int mode;
739 int res;
740
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000741 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000742 return NULL;
743 Py_BEGIN_ALLOW_THREADS
744 res = access(path, mode);
745 Py_END_ALLOW_THREADS
746 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000747}
748
Guido van Rossumd371ff11999-01-25 16:12:23 +0000749#ifndef F_OK
750#define F_OK 0
751#endif
752#ifndef R_OK
753#define R_OK 4
754#endif
755#ifndef W_OK
756#define W_OK 2
757#endif
758#ifndef X_OK
759#define X_OK 1
760#endif
761
762#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000763static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000764"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000765Return the name of the terminal device connected to 'fd'.";
766
767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000768posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000769{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000770 int id;
771 char *ret;
772
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000773 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000774 return NULL;
775
Guido van Rossum94f6f721999-01-06 18:42:14 +0000776 ret = ttyname(id);
777 if (ret == NULL)
778 return(posix_error());
779 return(PyString_FromString(ret));
780}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000781#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000782
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000783#ifdef HAVE_CTERMID
784static char posix_ctermid__doc__[] =
785"ctermid() -> String\n\
786Return the name of the controlling terminal for this process.";
787
788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000789posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000790{
791 char *ret;
792 char buffer[L_ctermid];
793
794 if (!PyArg_ParseTuple(args, ":ctermid"))
795 return NULL;
796
Greg Wardb48bc172000-03-01 21:51:56 +0000797#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000798 ret = ctermid_r(buffer);
799#else
800 ret = ctermid(buffer);
801#endif
802 if (ret == NULL)
803 return(posix_error());
804 return(PyString_FromString(buffer));
805}
806#endif
807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000808static char posix_chdir__doc__[] =
809"chdir(path) -> None\n\
810Change the current working directory to the specified path.";
811
Barry Warsaw53699e91996-12-10 23:23:01 +0000812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000813posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000814{
Mark Hammondef8b6542001-05-13 08:04:26 +0000815 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000816}
817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000818
819static char posix_chmod__doc__[] =
820"chmod(path, mode) -> None\n\
821Change the access permissions of a file.";
822
Barry Warsaw53699e91996-12-10 23:23:01 +0000823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000824posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000825{
Mark Hammondef8b6542001-05-13 08:04:26 +0000826 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000827 int i;
828 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000829 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
830 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000831 return NULL;
832 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000833 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000834 Py_END_ALLOW_THREADS
835 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000836 return posix_error_with_allocated_filename(path);
837 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000838 Py_INCREF(Py_None);
839 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000840}
841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000842
Martin v. Löwis244edc82001-10-04 22:44:26 +0000843#ifdef HAVE_CHROOT
844static char posix_chroot__doc__[] =
845"chroot(path) -> None\n\
846Change root directory to path.";
847
848static PyObject *
849posix_chroot(PyObject *self, PyObject *args)
850{
851 return posix_1str(args, "et:chroot", chroot);
852}
853#endif
854
Guido van Rossum21142a01999-01-08 21:05:37 +0000855#ifdef HAVE_FSYNC
856static char posix_fsync__doc__[] =
857"fsync(fildes) -> None\n\
858force write of file with filedescriptor to disk.";
859
860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000861posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000862{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000863 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000864}
865#endif /* HAVE_FSYNC */
866
867#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000868
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000869#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000870extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
871#endif
872
Guido van Rossum21142a01999-01-08 21:05:37 +0000873static char posix_fdatasync__doc__[] =
874"fdatasync(fildes) -> None\n\
875force write of file with filedescriptor to disk.\n\
876 does not force update of metadata.";
877
878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000879posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000880{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000881 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000882}
883#endif /* HAVE_FDATASYNC */
884
885
Fredrik Lundh10723342000-07-10 16:38:09 +0000886#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000887static char posix_chown__doc__[] =
888"chown(path, uid, gid) -> None\n\
889Change the owner and group id of path to the numeric uid and gid.";
890
Barry Warsaw53699e91996-12-10 23:23:01 +0000891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000892posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000893{
Mark Hammondef8b6542001-05-13 08:04:26 +0000894 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000895 int uid, gid;
896 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000897 if (!PyArg_ParseTuple(args, "etii:chown",
898 Py_FileSystemDefaultEncoding, &path,
899 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000900 return NULL;
901 Py_BEGIN_ALLOW_THREADS
902 res = chown(path, (uid_t) uid, (gid_t) gid);
903 Py_END_ALLOW_THREADS
904 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000905 return posix_error_with_allocated_filename(path);
906 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000907 Py_INCREF(Py_None);
908 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000909}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000910#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000912
Guido van Rossum36bc6801995-06-14 22:54:23 +0000913#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000914static char posix_getcwd__doc__[] =
915"getcwd() -> path\n\
916Return a string representing the current working directory.";
917
Barry Warsaw53699e91996-12-10 23:23:01 +0000918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000919posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920{
921 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000922 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000923 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000924 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000925 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000926 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000927 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000928 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000929 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000930 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000931}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000932#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000934
Guido van Rossumb6775db1994-08-01 11:34:53 +0000935#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000936static char posix_link__doc__[] =
937"link(src, dst) -> None\n\
938Create a hard link to a file.";
939
Barry Warsaw53699e91996-12-10 23:23:01 +0000940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000941posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000942{
Mark Hammondef8b6542001-05-13 08:04:26 +0000943 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000944}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000945#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000947
948static char posix_listdir__doc__[] =
949"listdir(path) -> list_of_strings\n\
950Return a list containing the names of the entries in the directory.\n\
951\n\
952 path: path of directory to list\n\
953\n\
954The list is in arbitrary order. It does not include the special\n\
955entries '.' and '..' even if they are present in the directory.";
956
Barry Warsaw53699e91996-12-10 23:23:01 +0000957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000958posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000959{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000960 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000961 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000962#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000963
Barry Warsaw53699e91996-12-10 23:23:01 +0000964 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000965 HANDLE hFindFile;
966 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000967 /* MAX_PATH characters could mean a bigger encoded string */
968 char namebuf[MAX_PATH*2+5];
969 char *bufptr = namebuf;
970 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000971 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000972
Mark Hammondef8b6542001-05-13 08:04:26 +0000973 if (!PyArg_ParseTuple(args, "et#:listdir",
974 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000975 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000976 ch = namebuf[len-1];
977 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000978 namebuf[len++] = '/';
979 strcpy(namebuf + len, "*.*");
980
Barry Warsaw53699e91996-12-10 23:23:01 +0000981 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000982 return NULL;
983
984 hFindFile = FindFirstFile(namebuf, &FileData);
985 if (hFindFile == INVALID_HANDLE_VALUE) {
986 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000987 if (errno == ERROR_FILE_NOT_FOUND)
988 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000989 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000990 }
991 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000992 if (FileData.cFileName[0] == '.' &&
993 (FileData.cFileName[1] == '\0' ||
994 FileData.cFileName[1] == '.' &&
995 FileData.cFileName[2] == '\0'))
996 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000997 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000998 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000999 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001000 d = NULL;
1001 break;
1002 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001003 if (PyList_Append(d, v) != 0) {
1004 Py_DECREF(v);
1005 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001006 d = NULL;
1007 break;
1008 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001009 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001010 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1011
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001012 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001013 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001014
1015 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001016
Tim Peters0bb44a42000-09-15 07:44:49 +00001017#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001018
1019#ifndef MAX_PATH
1020#define MAX_PATH 250
1021#endif
1022 char *name, *pt;
1023 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001024 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001025 char namebuf[MAX_PATH+5];
1026 struct _find_t ep;
1027
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001028 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001029 return NULL;
1030 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001031 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001032 return NULL;
1033 }
1034 strcpy(namebuf, name);
1035 for (pt = namebuf; *pt; pt++)
1036 if (*pt == '/')
1037 *pt = '\\';
1038 if (namebuf[len-1] != '\\')
1039 namebuf[len++] = '\\';
1040 strcpy(namebuf + len, "*.*");
1041
Barry Warsaw53699e91996-12-10 23:23:01 +00001042 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001043 return NULL;
1044
1045 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001046 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1047 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001048 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001049 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001050 }
1051 do {
1052 if (ep.name[0] == '.' &&
1053 (ep.name[1] == '\0' ||
1054 ep.name[1] == '.' &&
1055 ep.name[2] == '\0'))
1056 continue;
1057 strcpy(namebuf, ep.name);
1058 for (pt = namebuf; *pt; pt++)
1059 if (isupper(*pt))
1060 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001061 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001062 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001063 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001064 d = NULL;
1065 break;
1066 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001067 if (PyList_Append(d, v) != 0) {
1068 Py_DECREF(v);
1069 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001070 d = NULL;
1071 break;
1072 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001073 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001074 } while (_dos_findnext(&ep) == 0);
1075
1076 return d;
1077
Tim Peters0bb44a42000-09-15 07:44:49 +00001078#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001079
1080#ifndef MAX_PATH
1081#define MAX_PATH CCHMAXPATH
1082#endif
1083 char *name, *pt;
1084 int len;
1085 PyObject *d, *v;
1086 char namebuf[MAX_PATH+5];
1087 HDIR hdir = 1;
1088 ULONG srchcnt = 1;
1089 FILEFINDBUF3 ep;
1090 APIRET rc;
1091
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001092 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001093 return NULL;
1094 if (len >= MAX_PATH) {
1095 PyErr_SetString(PyExc_ValueError, "path too long");
1096 return NULL;
1097 }
1098 strcpy(namebuf, name);
1099 for (pt = namebuf; *pt; pt++)
1100 if (*pt == '/')
1101 *pt = '\\';
1102 if (namebuf[len-1] != '\\')
1103 namebuf[len++] = '\\';
1104 strcpy(namebuf + len, "*.*");
1105
1106 if ((d = PyList_New(0)) == NULL)
1107 return NULL;
1108
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001109 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1110 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001111 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001112 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1113 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1114 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001115
1116 if (rc != NO_ERROR) {
1117 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001118 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001119 }
1120
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001121 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001122 do {
1123 if (ep.achName[0] == '.'
1124 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001125 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001126
1127 strcpy(namebuf, ep.achName);
1128
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001129 /* Leave Case of Name Alone -- In Native Form */
1130 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001131
1132 v = PyString_FromString(namebuf);
1133 if (v == NULL) {
1134 Py_DECREF(d);
1135 d = NULL;
1136 break;
1137 }
1138 if (PyList_Append(d, v) != 0) {
1139 Py_DECREF(v);
1140 Py_DECREF(d);
1141 d = NULL;
1142 break;
1143 }
1144 Py_DECREF(v);
1145 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1146 }
1147
1148 return d;
1149#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001150
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001151 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001152 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001154 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001155 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001156 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001157 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001158 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001159 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001160 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001161 closedir(dirp);
1162 return NULL;
1163 }
1164 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001165 if (ep->d_name[0] == '.' &&
1166 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001167 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001168 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001169 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001170 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001171 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001172 d = NULL;
1173 break;
1174 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001175 if (PyList_Append(d, v) != 0) {
1176 Py_DECREF(v);
1177 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178 d = NULL;
1179 break;
1180 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001181 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182 }
1183 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001184
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001186
Tim Peters0bb44a42000-09-15 07:44:49 +00001187#endif /* which OS */
1188} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189
Mark Hammondef8b6542001-05-13 08:04:26 +00001190#ifdef MS_WIN32
1191/* A helper function for abspath on win32 */
1192static PyObject *
1193posix__getfullpathname(PyObject *self, PyObject *args)
1194{
1195 /* assume encoded strings wont more than double no of chars */
1196 char inbuf[MAX_PATH*2];
1197 char *inbufp = inbuf;
1198 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1199 char outbuf[MAX_PATH*2];
1200 char *temp;
1201 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1202 Py_FileSystemDefaultEncoding, &inbufp,
1203 &insize))
1204 return NULL;
1205 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1206 outbuf, &temp))
1207 return win32_error("GetFullPathName", inbuf);
1208 return PyString_FromString(outbuf);
1209} /* end of posix__getfullpathname */
1210#endif /* MS_WIN32 */
1211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001212static char posix_mkdir__doc__[] =
1213"mkdir(path [, mode=0777]) -> None\n\
1214Create a directory.";
1215
Barry Warsaw53699e91996-12-10 23:23:01 +00001216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001217posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001219 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001220 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001221 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001222 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1223 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001224 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001225 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001226#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001227 res = mkdir(path);
1228#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001229 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001230#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001231 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001232 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001233 return posix_error_with_allocated_filename(path);
1234 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001235 Py_INCREF(Py_None);
1236 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001237}
1238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001239
Guido van Rossumb6775db1994-08-01 11:34:53 +00001240#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001241#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1242#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1243#include <sys/resource.h>
1244#endif
1245#endif
1246
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001247static char posix_nice__doc__[] =
1248"nice(inc) -> new_priority\n\
1249Decrease the priority of process and return new priority.";
1250
Barry Warsaw53699e91996-12-10 23:23:01 +00001251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001252posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001253{
1254 int increment, value;
1255
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001256 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001257 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001258
1259 /* There are two flavours of 'nice': one that returns the new
1260 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001261 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1262 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001263
1264 If we are of the nice family that returns the new priority, we
1265 need to clear errno before the call, and check if errno is filled
1266 before calling posix_error() on a returnvalue of -1, because the
1267 -1 may be the actual new priority! */
1268
1269 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001270 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001271#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001272 if (value == 0)
1273 value = getpriority(PRIO_PROCESS, 0);
1274#endif
1275 if (value == -1 && errno != 0)
1276 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001277 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001278 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001279}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001280#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001281
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001282
1283static char posix_rename__doc__[] =
1284"rename(old, new) -> None\n\
1285Rename a file or directory.";
1286
Barry Warsaw53699e91996-12-10 23:23:01 +00001287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001288posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001289{
Mark Hammondef8b6542001-05-13 08:04:26 +00001290 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001291}
1292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001293
1294static char posix_rmdir__doc__[] =
1295"rmdir(path) -> None\n\
1296Remove a directory.";
1297
Barry Warsaw53699e91996-12-10 23:23:01 +00001298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001299posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001300{
Mark Hammondef8b6542001-05-13 08:04:26 +00001301 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001302}
1303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001304
1305static char posix_stat__doc__[] =
1306"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1307Perform a stat system call on the given path.";
1308
Barry Warsaw53699e91996-12-10 23:23:01 +00001309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001310posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001311{
Mark Hammondef8b6542001-05-13 08:04:26 +00001312 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001313}
1314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001315
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001316#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001317static char posix_system__doc__[] =
1318"system(command) -> exit_status\n\
1319Execute the command (a string) in a subshell.";
1320
Barry Warsaw53699e91996-12-10 23:23:01 +00001321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001322posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001323{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001324 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001325 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001326 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001327 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001328 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001329 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001330 Py_END_ALLOW_THREADS
1331 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001332}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001333#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
1336static char posix_umask__doc__[] =
1337"umask(new_mask) -> old_mask\n\
1338Set the current numeric umask and return the previous umask.";
1339
Barry Warsaw53699e91996-12-10 23:23:01 +00001340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001341posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342{
1343 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001344 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001345 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001346 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001347 if (i < 0)
1348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001349 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350}
1351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001352
1353static char posix_unlink__doc__[] =
1354"unlink(path) -> None\n\
1355Remove a file (same as remove(path)).";
1356
1357static char posix_remove__doc__[] =
1358"remove(path) -> None\n\
1359Remove a file (same as unlink(path)).";
1360
Barry Warsaw53699e91996-12-10 23:23:01 +00001361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001362posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001363{
Mark Hammondef8b6542001-05-13 08:04:26 +00001364 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365}
1366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001367
Guido van Rossumb6775db1994-08-01 11:34:53 +00001368#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001369static char posix_uname__doc__[] =
1370"uname() -> (sysname, nodename, release, version, machine)\n\
1371Return a tuple identifying the current operating system.";
1372
Barry Warsaw53699e91996-12-10 23:23:01 +00001373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001374posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001375{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001376 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001377 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001378 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001379 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001380 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001381 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001382 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001383 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001384 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001385 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001386 u.sysname,
1387 u.nodename,
1388 u.release,
1389 u.version,
1390 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001391}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001392#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001394
1395static char posix_utime__doc__[] =
1396"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001397utime(path, None) -> None\n\
1398Set the access and modified time of the file to the given values. If the\n\
1399second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001400
Barry Warsaw53699e91996-12-10 23:23:01 +00001401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001402posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001403{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001404 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001405 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001406 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001407 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001408
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001409/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001410#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001411 struct utimbuf buf;
1412#define ATIME buf.actime
1413#define MTIME buf.modtime
1414#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001415#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001416 time_t buf[2];
1417#define ATIME buf[0]
1418#define MTIME buf[1]
1419#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001420#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001421
Barry Warsaw3cef8562000-05-01 16:17:24 +00001422 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001424 if (arg == Py_None) {
1425 /* optional time values not given */
1426 Py_BEGIN_ALLOW_THREADS
1427 res = utime(path, NULL);
1428 Py_END_ALLOW_THREADS
1429 }
1430 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1431 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001432 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001433 return NULL;
1434 }
1435 else {
1436 ATIME = atime;
1437 MTIME = mtime;
1438 Py_BEGIN_ALLOW_THREADS
1439 res = utime(path, UTIME_ARG);
1440 Py_END_ALLOW_THREADS
1441 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001442 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001443 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001444 Py_INCREF(Py_None);
1445 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001446#undef UTIME_ARG
1447#undef ATIME
1448#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001449}
1450
Guido van Rossum85e3b011991-06-03 12:42:10 +00001451
Guido van Rossum3b066191991-06-04 19:40:25 +00001452/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001453
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001454static char posix__exit__doc__[] =
1455"_exit(status)\n\
1456Exit to the system with specified status, without normal exit processing.";
1457
Barry Warsaw53699e91996-12-10 23:23:01 +00001458static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001459posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001460{
1461 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001462 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001463 return NULL;
1464 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001465 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001466}
1467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001468
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001469#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001470static char posix_execv__doc__[] =
1471"execv(path, args)\n\
1472Execute an executable path with arguments, replacing current process.\n\
1473\n\
1474 path: path of executable file\n\
1475 args: tuple or list of strings";
1476
Barry Warsaw53699e91996-12-10 23:23:01 +00001477static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001478posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001479{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001480 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001481 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001482 char **argvlist;
1483 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001484 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001485
Guido van Rossum89b33251993-10-22 14:26:06 +00001486 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001487 argv is a list or tuple of strings. */
1488
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001489 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001490 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001491 if (PyList_Check(argv)) {
1492 argc = PyList_Size(argv);
1493 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001494 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001495 else if (PyTuple_Check(argv)) {
1496 argc = PyTuple_Size(argv);
1497 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001498 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001499 else {
Fred Drake661ea262000-10-24 19:57:45 +00001500 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001501 return NULL;
1502 }
1503
1504 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001505 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001506 return NULL;
1507 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001508
Barry Warsaw53699e91996-12-10 23:23:01 +00001509 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001510 if (argvlist == NULL)
1511 return NULL;
1512 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001513 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1514 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001515 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001516 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001517 return NULL;
1518
Guido van Rossum85e3b011991-06-03 12:42:10 +00001519 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001520 }
1521 argvlist[argc] = NULL;
1522
Guido van Rossumb6775db1994-08-01 11:34:53 +00001523#ifdef BAD_EXEC_PROTOTYPES
1524 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001525#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001526 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001527#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001528
Guido van Rossum85e3b011991-06-03 12:42:10 +00001529 /* If we get here it's definitely an error */
1530
Barry Warsaw53699e91996-12-10 23:23:01 +00001531 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001532 return posix_error();
1533}
1534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001535
1536static char posix_execve__doc__[] =
1537"execve(path, args, env)\n\
1538Execute a path with arguments and environment, replacing current process.\n\
1539\n\
1540 path: path of executable file\n\
1541 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001542 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001543
Barry Warsaw53699e91996-12-10 23:23:01 +00001544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001545posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001546{
1547 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001548 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001549 char **argvlist;
1550 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001551 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001552 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001553 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001554
1555 /* execve has three arguments: (path, argv, env), where
1556 argv is a list or tuple of strings and env is a dictionary
1557 like posix.environ. */
1558
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001559 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001560 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001561 if (PyList_Check(argv)) {
1562 argc = PyList_Size(argv);
1563 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001564 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001565 else if (PyTuple_Check(argv)) {
1566 argc = PyTuple_Size(argv);
1567 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001568 }
1569 else {
Fred Drake661ea262000-10-24 19:57:45 +00001570 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001571 return NULL;
1572 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001573 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001574 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001575 return NULL;
1576 }
1577
Guido van Rossum50422b42000-04-26 20:34:28 +00001578 if (argc == 0) {
1579 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001580 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001581 return NULL;
1582 }
1583
Barry Warsaw53699e91996-12-10 23:23:01 +00001584 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001585 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001586 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001587 return NULL;
1588 }
1589 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001590 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001591 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001592 &argvlist[i]))
1593 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001594 goto fail_1;
1595 }
1596 }
1597 argvlist[argc] = NULL;
1598
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001599 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001600 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001602 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001603 goto fail_1;
1604 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001605 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001606 keys = PyMapping_Keys(env);
1607 vals = PyMapping_Values(env);
1608 if (!keys || !vals)
1609 goto fail_2;
1610
1611 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001612 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001613 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001614
1615 key = PyList_GetItem(keys, pos);
1616 val = PyList_GetItem(vals, pos);
1617 if (!key || !val)
1618 goto fail_2;
1619
Fred Drake661ea262000-10-24 19:57:45 +00001620 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1621 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001622 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001623 goto fail_2;
1624 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001625
1626#if defined(PYOS_OS2)
1627 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1628 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1629#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001630 len = PyString_Size(key) + PyString_Size(val) + 2;
1631 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001632 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001633 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001634 goto fail_2;
1635 }
Tim Petersc8996f52001-12-03 20:41:00 +00001636 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001637 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001638#if defined(PYOS_OS2)
1639 }
1640#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001641 }
1642 envlist[envc] = 0;
1643
Guido van Rossumb6775db1994-08-01 11:34:53 +00001644
1645#ifdef BAD_EXEC_PROTOTYPES
1646 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001647#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001648 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001649#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001650
1651 /* If we get here it's definitely an error */
1652
1653 (void) posix_error();
1654
1655 fail_2:
1656 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001657 PyMem_DEL(envlist[envc]);
1658 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001659 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001660 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001661 Py_XDECREF(vals);
1662 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001663 return NULL;
1664}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001665#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001667
Guido van Rossuma1065681999-01-25 23:20:23 +00001668#ifdef HAVE_SPAWNV
1669static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001670"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001671Execute an executable path with arguments, replacing current process.\n\
1672\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001673 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001674 path: path of executable file\n\
1675 args: tuple or list of strings";
1676
1677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001678posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001679{
1680 char *path;
1681 PyObject *argv;
1682 char **argvlist;
1683 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001684 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001685 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001686
1687 /* spawnv has three arguments: (mode, path, argv), where
1688 argv is a list or tuple of strings. */
1689
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001690 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001691 return NULL;
1692 if (PyList_Check(argv)) {
1693 argc = PyList_Size(argv);
1694 getitem = PyList_GetItem;
1695 }
1696 else if (PyTuple_Check(argv)) {
1697 argc = PyTuple_Size(argv);
1698 getitem = PyTuple_GetItem;
1699 }
1700 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001701 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001702 return NULL;
1703 }
1704
1705 argvlist = PyMem_NEW(char *, argc+1);
1706 if (argvlist == NULL)
1707 return NULL;
1708 for (i = 0; i < argc; i++) {
1709 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1710 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001711 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001712 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001713 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001714 }
1715 }
1716 argvlist[argc] = NULL;
1717
Guido van Rossum246bc171999-02-01 23:54:31 +00001718 if (mode == _OLD_P_OVERLAY)
1719 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001720 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001721
1722 PyMem_DEL(argvlist);
1723
Fred Drake699f3522000-06-29 21:12:41 +00001724 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001725 return posix_error();
1726 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001727#if SIZEOF_LONG == SIZEOF_VOID_P
1728 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001729#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001730 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001731#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001732}
1733
1734
1735static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001736"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001737Execute a path with arguments and environment, replacing current process.\n\
1738\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001739 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001740 path: path of executable file\n\
1741 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001742 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001743
1744static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001745posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001746{
1747 char *path;
1748 PyObject *argv, *env;
1749 char **argvlist;
1750 char **envlist;
1751 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1752 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001753 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001754 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001755
1756 /* spawnve has four arguments: (mode, path, argv, env), where
1757 argv is a list or tuple of strings and env is a dictionary
1758 like posix.environ. */
1759
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001760 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001761 return NULL;
1762 if (PyList_Check(argv)) {
1763 argc = PyList_Size(argv);
1764 getitem = PyList_GetItem;
1765 }
1766 else if (PyTuple_Check(argv)) {
1767 argc = PyTuple_Size(argv);
1768 getitem = PyTuple_GetItem;
1769 }
1770 else {
Fred Drake661ea262000-10-24 19:57:45 +00001771 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001772 return NULL;
1773 }
1774 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001775 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001776 return NULL;
1777 }
1778
1779 argvlist = PyMem_NEW(char *, argc+1);
1780 if (argvlist == NULL) {
1781 PyErr_NoMemory();
1782 return NULL;
1783 }
1784 for (i = 0; i < argc; i++) {
1785 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001786 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001787 &argvlist[i]))
1788 {
1789 goto fail_1;
1790 }
1791 }
1792 argvlist[argc] = NULL;
1793
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001794 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001795 envlist = PyMem_NEW(char *, i + 1);
1796 if (envlist == NULL) {
1797 PyErr_NoMemory();
1798 goto fail_1;
1799 }
1800 envc = 0;
1801 keys = PyMapping_Keys(env);
1802 vals = PyMapping_Values(env);
1803 if (!keys || !vals)
1804 goto fail_2;
1805
1806 for (pos = 0; pos < i; pos++) {
1807 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001808 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001809
1810 key = PyList_GetItem(keys, pos);
1811 val = PyList_GetItem(vals, pos);
1812 if (!key || !val)
1813 goto fail_2;
1814
Fred Drake661ea262000-10-24 19:57:45 +00001815 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1816 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001817 {
1818 goto fail_2;
1819 }
Tim Petersc8996f52001-12-03 20:41:00 +00001820 len = PyString_Size(key) + PyString_Size(val) + 2;
1821 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001822 if (p == NULL) {
1823 PyErr_NoMemory();
1824 goto fail_2;
1825 }
Tim Petersc8996f52001-12-03 20:41:00 +00001826 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001827 envlist[envc++] = p;
1828 }
1829 envlist[envc] = 0;
1830
Guido van Rossum246bc171999-02-01 23:54:31 +00001831 if (mode == _OLD_P_OVERLAY)
1832 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001833 spawnval = _spawnve(mode, path, argvlist, envlist);
1834 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001835 (void) posix_error();
1836 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001837#if SIZEOF_LONG == SIZEOF_VOID_P
1838 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001839#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001840 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001841#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001842
1843 fail_2:
1844 while (--envc >= 0)
1845 PyMem_DEL(envlist[envc]);
1846 PyMem_DEL(envlist);
1847 fail_1:
1848 PyMem_DEL(argvlist);
1849 Py_XDECREF(vals);
1850 Py_XDECREF(keys);
1851 return res;
1852}
1853#endif /* HAVE_SPAWNV */
1854
1855
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001856#ifdef HAVE_FORK1
1857static char posix_fork1__doc__[] =
1858"fork1() -> pid\n\
1859Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1860\n\
1861Return 0 to child process and PID of child to parent process.";
1862
1863static PyObject *
1864posix_fork1(self, args)
1865 PyObject *self;
1866 PyObject *args;
1867{
1868 int pid;
1869 if (!PyArg_ParseTuple(args, ":fork1"))
1870 return NULL;
1871 pid = fork1();
1872 if (pid == -1)
1873 return posix_error();
1874 PyOS_AfterFork();
1875 return PyInt_FromLong((long)pid);
1876}
1877#endif
1878
1879
Guido van Rossumad0ee831995-03-01 10:34:45 +00001880#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001881static char posix_fork__doc__[] =
1882"fork() -> pid\n\
1883Fork a child process.\n\
1884\n\
1885Return 0 to child process and PID of child to parent process.";
1886
Barry Warsaw53699e91996-12-10 23:23:01 +00001887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001888posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001889{
1890 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001891 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001892 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001893 pid = fork();
1894 if (pid == -1)
1895 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001896 if (pid == 0)
1897 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001898 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001899}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001900#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001901
Fred Drake8cef4cf2000-06-28 16:40:38 +00001902#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1903#ifdef HAVE_PTY_H
1904#include <pty.h>
1905#else
1906#ifdef HAVE_LIBUTIL_H
1907#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001908#endif /* HAVE_LIBUTIL_H */
1909#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001910#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001911
Thomas Wouters70c21a12000-07-14 14:28:33 +00001912#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001913static char posix_openpty__doc__[] =
1914"openpty() -> (master_fd, slave_fd)\n\
1915Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1916
1917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001918posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001919{
1920 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001921#ifndef HAVE_OPENPTY
1922 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001923#endif
1924
Fred Drake8cef4cf2000-06-28 16:40:38 +00001925 if (!PyArg_ParseTuple(args, ":openpty"))
1926 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001927
1928#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001929 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1930 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001931#else
1932 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1933 if (slave_name == NULL)
1934 return posix_error();
1935
1936 slave_fd = open(slave_name, O_RDWR);
1937 if (slave_fd < 0)
1938 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001939#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001940
Fred Drake8cef4cf2000-06-28 16:40:38 +00001941 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001942
Fred Drake8cef4cf2000-06-28 16:40:38 +00001943}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001944#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001945
1946#ifdef HAVE_FORKPTY
1947static char posix_forkpty__doc__[] =
1948"forkpty() -> (pid, master_fd)\n\
1949Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1950Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1951To both, return fd of newly opened pseudo-terminal.\n";
1952
1953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001954posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001955{
1956 int master_fd, pid;
1957
1958 if (!PyArg_ParseTuple(args, ":forkpty"))
1959 return NULL;
1960 pid = forkpty(&master_fd, NULL, NULL, NULL);
1961 if (pid == -1)
1962 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001963 if (pid == 0)
1964 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001965 return Py_BuildValue("(ii)", pid, master_fd);
1966}
1967#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001968
Guido van Rossumad0ee831995-03-01 10:34:45 +00001969#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001970static char posix_getegid__doc__[] =
1971"getegid() -> egid\n\
1972Return the current process's effective group id.";
1973
Barry Warsaw53699e91996-12-10 23:23:01 +00001974static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001975posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001976{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001977 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001978 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001979 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001980}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001981#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001983
Guido van Rossumad0ee831995-03-01 10:34:45 +00001984#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001985static char posix_geteuid__doc__[] =
1986"geteuid() -> euid\n\
1987Return the current process's effective user id.";
1988
Barry Warsaw53699e91996-12-10 23:23:01 +00001989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001990posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001991{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001992 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001993 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001994 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001995}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001996#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001997
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001998
Guido van Rossumad0ee831995-03-01 10:34:45 +00001999#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002000static char posix_getgid__doc__[] =
2001"getgid() -> gid\n\
2002Return the current process's group id.";
2003
Barry Warsaw53699e91996-12-10 23:23:01 +00002004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002005posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002006{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002007 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002008 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002009 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002010}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002011#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002013
2014static char posix_getpid__doc__[] =
2015"getpid() -> pid\n\
2016Return the current process id";
2017
Barry Warsaw53699e91996-12-10 23:23:01 +00002018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002019posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002020{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002021 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002022 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002023 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002024}
2025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002026
Fred Drakec9680921999-12-13 16:37:25 +00002027#ifdef HAVE_GETGROUPS
2028static char posix_getgroups__doc__[] = "\
2029getgroups() -> list of group IDs\n\
2030Return list of supplemental group IDs for the process.";
2031
2032static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002033posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002034{
2035 PyObject *result = NULL;
2036
2037 if (PyArg_ParseTuple(args, ":getgroups")) {
2038#ifdef NGROUPS_MAX
2039#define MAX_GROUPS NGROUPS_MAX
2040#else
2041 /* defined to be 16 on Solaris7, so this should be a small number */
2042#define MAX_GROUPS 64
2043#endif
2044 gid_t grouplist[MAX_GROUPS];
2045 int n;
2046
2047 n = getgroups(MAX_GROUPS, grouplist);
2048 if (n < 0)
2049 posix_error();
2050 else {
2051 result = PyList_New(n);
2052 if (result != NULL) {
2053 PyObject *o;
2054 int i;
2055 for (i = 0; i < n; ++i) {
2056 o = PyInt_FromLong((long)grouplist[i]);
2057 if (o == NULL) {
2058 Py_DECREF(result);
2059 result = NULL;
2060 break;
2061 }
2062 PyList_SET_ITEM(result, i, o);
2063 }
2064 }
2065 }
2066 }
2067 return result;
2068}
2069#endif
2070
Guido van Rossumb6775db1994-08-01 11:34:53 +00002071#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002072static char posix_getpgrp__doc__[] =
2073"getpgrp() -> pgrp\n\
2074Return the current process group id.";
2075
Barry Warsaw53699e91996-12-10 23:23:01 +00002076static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002077posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002078{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002079 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002080 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002081#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002082 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002083#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002084 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002085#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002086}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002087#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002089
Guido van Rossumb6775db1994-08-01 11:34:53 +00002090#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002091static char posix_setpgrp__doc__[] =
2092"setpgrp() -> None\n\
2093Make this process a session leader.";
2094
Barry Warsaw53699e91996-12-10 23:23:01 +00002095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002096posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002097{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002098 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002099 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002100#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002101 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002102#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002103 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002104#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002105 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002106 Py_INCREF(Py_None);
2107 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002108}
2109
Guido van Rossumb6775db1994-08-01 11:34:53 +00002110#endif /* HAVE_SETPGRP */
2111
Guido van Rossumad0ee831995-03-01 10:34:45 +00002112#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002113static char posix_getppid__doc__[] =
2114"getppid() -> ppid\n\
2115Return the parent's process id.";
2116
Barry Warsaw53699e91996-12-10 23:23:01 +00002117static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002118posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002119{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002120 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002121 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002122 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002123}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002124#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002125
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002126
Fred Drake12c6e2d1999-12-14 21:25:03 +00002127#ifdef HAVE_GETLOGIN
2128static char posix_getlogin__doc__[] = "\
2129getlogin() -> string\n\
2130Return the actual login name.";
2131
2132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002133posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002134{
2135 PyObject *result = NULL;
2136
2137 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002138 char *name;
2139 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002140
Fred Drakea30680b2000-12-06 21:24:28 +00002141 errno = 0;
2142 name = getlogin();
2143 if (name == NULL) {
2144 if (errno)
2145 posix_error();
2146 else
2147 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002148 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002149 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002150 else
2151 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002152 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002153 }
2154 return result;
2155}
2156#endif
2157
Guido van Rossumad0ee831995-03-01 10:34:45 +00002158#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002159static char posix_getuid__doc__[] =
2160"getuid() -> uid\n\
2161Return the current process's user id.";
2162
Barry Warsaw53699e91996-12-10 23:23:01 +00002163static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002164posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002165{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002166 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002167 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002168 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002169}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002170#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002171
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002172
Guido van Rossumad0ee831995-03-01 10:34:45 +00002173#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002174static char posix_kill__doc__[] =
2175"kill(pid, sig) -> None\n\
2176Kill a process with a signal.";
2177
Barry Warsaw53699e91996-12-10 23:23:01 +00002178static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002179posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002180{
2181 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002182 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002183 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002184#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002185 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2186 APIRET rc;
2187 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002188 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002189
2190 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2191 APIRET rc;
2192 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002193 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002194
2195 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002196 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002197#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002198 if (kill(pid, sig) == -1)
2199 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002200#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002201 Py_INCREF(Py_None);
2202 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002203}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002204#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002205
Guido van Rossumc0125471996-06-28 18:55:32 +00002206#ifdef HAVE_PLOCK
2207
2208#ifdef HAVE_SYS_LOCK_H
2209#include <sys/lock.h>
2210#endif
2211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002212static char posix_plock__doc__[] =
2213"plock(op) -> None\n\
2214Lock program segments into memory.";
2215
Barry Warsaw53699e91996-12-10 23:23:01 +00002216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002217posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002218{
2219 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002220 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002221 return NULL;
2222 if (plock(op) == -1)
2223 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002224 Py_INCREF(Py_None);
2225 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002226}
2227#endif
2228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002229
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002230#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002231static char posix_popen__doc__[] =
2232"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2233Open a pipe to/from a command returning a file object.";
2234
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002235#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002236static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002237async_system(const char *command)
2238{
2239 char *p, errormsg[256], args[1024];
2240 RESULTCODES rcodes;
2241 APIRET rc;
2242 char *shell = getenv("COMSPEC");
2243 if (!shell)
2244 shell = "cmd";
2245
2246 strcpy(args, shell);
2247 p = &args[ strlen(args)+1 ];
2248 strcpy(p, "/c ");
2249 strcat(p, command);
2250 p += strlen(p) + 1;
2251 *p = '\0';
2252
2253 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002254 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002255 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002256 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002257 &rcodes, shell);
2258 return rc;
2259}
2260
Guido van Rossumd48f2521997-12-05 22:19:34 +00002261static FILE *
2262popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002263{
2264 HFILE rhan, whan;
2265 FILE *retfd = NULL;
2266 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2267
Guido van Rossumd48f2521997-12-05 22:19:34 +00002268 if (rc != NO_ERROR) {
2269 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002270 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002271 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002272
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002273 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2274 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002275
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002276 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2277 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002278
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002279 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2280 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002281
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002282 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283 }
2284
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002285 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2286 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002287
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002288 if (rc == NO_ERROR)
2289 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2290
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002291 close(oldfd); /* And Close Saved STDOUT Handle */
2292 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002293
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002294 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2295 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002296
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002297 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2298 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002299
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002300 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2301 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002302
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002303 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002304 }
2305
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002306 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2307 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002308
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002309 if (rc == NO_ERROR)
2310 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2311
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002312 close(oldfd); /* And Close Saved STDIN Handle */
2313 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002314
Guido van Rossumd48f2521997-12-05 22:19:34 +00002315 } else {
2316 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002317 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002318 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002319}
2320
2321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002322posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323{
2324 char *name;
2325 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002326 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002327 FILE *fp;
2328 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002329 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002330 return NULL;
2331 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002332 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002333 Py_END_ALLOW_THREADS
2334 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002335 return os2_error(err);
2336
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337 f = PyFile_FromFile(fp, name, mode, fclose);
2338 if (f != NULL)
2339 PyFile_SetBufSize(f, bufsize);
2340 return f;
2341}
2342
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002343#elif defined(MS_WIN32)
2344
2345/*
2346 * Portable 'popen' replacement for Win32.
2347 *
2348 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2349 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002350 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002351 */
2352
2353#include <malloc.h>
2354#include <io.h>
2355#include <fcntl.h>
2356
2357/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2358#define POPEN_1 1
2359#define POPEN_2 2
2360#define POPEN_3 3
2361#define POPEN_4 4
2362
2363static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002364static int _PyPclose(FILE *file);
2365
2366/*
2367 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002368 * for use when retrieving the process exit code. See _PyPclose() below
2369 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002370 */
2371static PyObject *_PyPopenProcs = NULL;
2372
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002373
2374/* popen that works from a GUI.
2375 *
2376 * The result of this function is a pipe (file) connected to the
2377 * processes stdin or stdout, depending on the requested mode.
2378 */
2379
2380static PyObject *
2381posix_popen(PyObject *self, PyObject *args)
2382{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002383 PyObject *f, *s;
2384 int tm = 0;
2385
2386 char *cmdstring;
2387 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002388 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002389 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002390 return NULL;
2391
2392 s = PyTuple_New(0);
2393
2394 if (*mode == 'r')
2395 tm = _O_RDONLY;
2396 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002397 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002398 return NULL;
2399 } else
2400 tm = _O_WRONLY;
2401
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002402 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002403 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002404 return NULL;
2405 }
2406
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002407 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002408 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002409 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002410 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002411 else
2412 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2413
2414 return f;
2415}
2416
2417/* Variation on win32pipe.popen
2418 *
2419 * The result of this function is a pipe (file) connected to the
2420 * process's stdin, and a pipe connected to the process's stdout.
2421 */
2422
2423static PyObject *
2424win32_popen2(PyObject *self, PyObject *args)
2425{
2426 PyObject *f;
2427 int tm=0;
2428
2429 char *cmdstring;
2430 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002431 int bufsize = -1;
2432 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002433 return NULL;
2434
2435 if (*mode == 't')
2436 tm = _O_TEXT;
2437 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002438 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002439 return NULL;
2440 } else
2441 tm = _O_BINARY;
2442
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002443 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002444 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002445 return NULL;
2446 }
2447
2448 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002449
2450 return f;
2451}
2452
2453/*
2454 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002455 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002456 * The result of this function is 3 pipes - the process's stdin,
2457 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002458 */
2459
2460static PyObject *
2461win32_popen3(PyObject *self, PyObject *args)
2462{
2463 PyObject *f;
2464 int tm = 0;
2465
2466 char *cmdstring;
2467 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002468 int bufsize = -1;
2469 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002470 return NULL;
2471
2472 if (*mode == 't')
2473 tm = _O_TEXT;
2474 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002475 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002476 return NULL;
2477 } else
2478 tm = _O_BINARY;
2479
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002480 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002481 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002482 return NULL;
2483 }
2484
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002485 f = _PyPopen(cmdstring, tm, POPEN_3);
2486
2487 return f;
2488}
2489
2490/*
2491 * Variation on win32pipe.popen
2492 *
2493 * The result of this function is 2 pipes - the processes stdin,
2494 * and stdout+stderr combined as a single pipe.
2495 */
2496
2497static PyObject *
2498win32_popen4(PyObject *self, PyObject *args)
2499{
2500 PyObject *f;
2501 int tm = 0;
2502
2503 char *cmdstring;
2504 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002505 int bufsize = -1;
2506 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002507 return NULL;
2508
2509 if (*mode == 't')
2510 tm = _O_TEXT;
2511 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002512 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002513 return NULL;
2514 } else
2515 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002516
2517 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002518 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002519 return NULL;
2520 }
2521
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002522 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002523
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002524 return f;
2525}
2526
Mark Hammond08501372001-01-31 07:30:29 +00002527static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002528_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002529 HANDLE hStdin,
2530 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002531 HANDLE hStderr,
2532 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002533{
2534 PROCESS_INFORMATION piProcInfo;
2535 STARTUPINFO siStartInfo;
2536 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002537 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002538 int i;
2539 int x;
2540
2541 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002542 char *comshell;
2543
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002544 s1 = (char *)_alloca(i);
2545 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2546 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002547
2548 /* Explicitly check if we are using COMMAND.COM. If we are
2549 * then use the w9xpopen hack.
2550 */
2551 comshell = s1 + x;
2552 while (comshell >= s1 && *comshell != '\\')
2553 --comshell;
2554 ++comshell;
2555
2556 if (GetVersion() < 0x80000000 &&
2557 _stricmp(comshell, "command.com") != 0) {
2558 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002559 x = i + strlen(s3) + strlen(cmdstring) + 1;
2560 s2 = (char *)_alloca(x);
2561 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002562 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002563 }
2564 else {
2565 /*
Tim Peters402d5982001-08-27 06:37:48 +00002566 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2567 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002568 */
Mark Hammond08501372001-01-31 07:30:29 +00002569 char modulepath[_MAX_PATH];
2570 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002571 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2572 for (i = x = 0; modulepath[i]; i++)
2573 if (modulepath[i] == '\\')
2574 x = i+1;
2575 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002576 /* Create the full-name to w9xpopen, so we can test it exists */
2577 strncat(modulepath,
2578 szConsoleSpawn,
2579 (sizeof(modulepath)/sizeof(modulepath[0]))
2580 -strlen(modulepath));
2581 if (stat(modulepath, &statinfo) != 0) {
2582 /* Eeek - file-not-found - possibly an embedding
2583 situation - see if we can locate it in sys.prefix
2584 */
2585 strncpy(modulepath,
2586 Py_GetExecPrefix(),
2587 sizeof(modulepath)/sizeof(modulepath[0]));
2588 if (modulepath[strlen(modulepath)-1] != '\\')
2589 strcat(modulepath, "\\");
2590 strncat(modulepath,
2591 szConsoleSpawn,
2592 (sizeof(modulepath)/sizeof(modulepath[0]))
2593 -strlen(modulepath));
2594 /* No where else to look - raise an easily identifiable
2595 error, rather than leaving Windows to report
2596 "file not found" - as the user is probably blissfully
2597 unaware this shim EXE is used, and it will confuse them.
2598 (well, it confused me for a while ;-)
2599 */
2600 if (stat(modulepath, &statinfo) != 0) {
2601 PyErr_Format(PyExc_RuntimeError,
2602 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002603 "for popen to work with your shell "
2604 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002605 szConsoleSpawn);
2606 return FALSE;
2607 }
2608 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002609 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2610 strlen(modulepath) +
2611 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002612
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002613 s2 = (char *)_alloca(x);
2614 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002615 PyOS_snprintf(
2616 s2, x,
Mark Hammond08501372001-01-31 07:30:29 +00002617 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002618 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002619 s1,
2620 s3,
2621 cmdstring);
2622 }
2623 }
2624
2625 /* Could be an else here to try cmd.exe / command.com in the path
2626 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002627 else {
Tim Peters402d5982001-08-27 06:37:48 +00002628 PyErr_SetString(PyExc_RuntimeError,
2629 "Cannot locate a COMSPEC environment variable to "
2630 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002631 return FALSE;
2632 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002633
2634 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2635 siStartInfo.cb = sizeof(STARTUPINFO);
2636 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2637 siStartInfo.hStdInput = hStdin;
2638 siStartInfo.hStdOutput = hStdout;
2639 siStartInfo.hStdError = hStderr;
2640 siStartInfo.wShowWindow = SW_HIDE;
2641
2642 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002643 s2,
2644 NULL,
2645 NULL,
2646 TRUE,
2647 CREATE_NEW_CONSOLE,
2648 NULL,
2649 NULL,
2650 &siStartInfo,
2651 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002652 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002653 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002654
Mark Hammondb37a3732000-08-14 04:47:33 +00002655 /* Return process handle */
2656 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002657 return TRUE;
2658 }
Tim Peters402d5982001-08-27 06:37:48 +00002659 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002660 return FALSE;
2661}
2662
2663/* The following code is based off of KB: Q190351 */
2664
2665static PyObject *
2666_PyPopen(char *cmdstring, int mode, int n)
2667{
2668 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2669 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002670 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002671
2672 SECURITY_ATTRIBUTES saAttr;
2673 BOOL fSuccess;
2674 int fd1, fd2, fd3;
2675 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002676 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002677 PyObject *f;
2678
2679 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2680 saAttr.bInheritHandle = TRUE;
2681 saAttr.lpSecurityDescriptor = NULL;
2682
2683 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2684 return win32_error("CreatePipe", NULL);
2685
2686 /* Create new output read handle and the input write handle. Set
2687 * the inheritance properties to FALSE. Otherwise, the child inherits
2688 * the these handles; resulting in non-closeable handles to the pipes
2689 * being created. */
2690 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002691 GetCurrentProcess(), &hChildStdinWrDup, 0,
2692 FALSE,
2693 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002694 if (!fSuccess)
2695 return win32_error("DuplicateHandle", NULL);
2696
2697 /* Close the inheritable version of ChildStdin
2698 that we're using. */
2699 CloseHandle(hChildStdinWr);
2700
2701 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2702 return win32_error("CreatePipe", NULL);
2703
2704 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002705 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2706 FALSE, 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 ChildStdout
2711 that we're using. */
2712 CloseHandle(hChildStdoutRd);
2713
2714 if (n != POPEN_4) {
2715 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2716 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002717 fSuccess = DuplicateHandle(GetCurrentProcess(),
2718 hChildStderrRd,
2719 GetCurrentProcess(),
2720 &hChildStderrRdDup, 0,
2721 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002722 if (!fSuccess)
2723 return win32_error("DuplicateHandle", NULL);
2724 /* Close the inheritable version of ChildStdErr that we're using. */
2725 CloseHandle(hChildStderrRd);
2726 }
2727
2728 switch (n) {
2729 case POPEN_1:
2730 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2731 case _O_WRONLY | _O_TEXT:
2732 /* Case for writing to child Stdin in text mode. */
2733 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2734 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002735 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002736 PyFile_SetBufSize(f, 0);
2737 /* We don't care about these pipes anymore, so close them. */
2738 CloseHandle(hChildStdoutRdDup);
2739 CloseHandle(hChildStderrRdDup);
2740 break;
2741
2742 case _O_RDONLY | _O_TEXT:
2743 /* Case for reading from child Stdout in text mode. */
2744 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2745 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002746 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002747 PyFile_SetBufSize(f, 0);
2748 /* We don't care about these pipes anymore, so close them. */
2749 CloseHandle(hChildStdinWrDup);
2750 CloseHandle(hChildStderrRdDup);
2751 break;
2752
2753 case _O_RDONLY | _O_BINARY:
2754 /* Case for readinig from child Stdout in binary mode. */
2755 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2756 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002757 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002758 PyFile_SetBufSize(f, 0);
2759 /* We don't care about these pipes anymore, so close them. */
2760 CloseHandle(hChildStdinWrDup);
2761 CloseHandle(hChildStderrRdDup);
2762 break;
2763
2764 case _O_WRONLY | _O_BINARY:
2765 /* Case for writing to child Stdin in binary mode. */
2766 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2767 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002768 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002769 PyFile_SetBufSize(f, 0);
2770 /* We don't care about these pipes anymore, so close them. */
2771 CloseHandle(hChildStdoutRdDup);
2772 CloseHandle(hChildStderrRdDup);
2773 break;
2774 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002775 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002776 break;
2777
2778 case POPEN_2:
2779 case POPEN_4:
2780 {
2781 char *m1, *m2;
2782 PyObject *p1, *p2;
2783
2784 if (mode && _O_TEXT) {
2785 m1 = "r";
2786 m2 = "w";
2787 } else {
2788 m1 = "rb";
2789 m2 = "wb";
2790 }
2791
2792 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2793 f1 = _fdopen(fd1, m2);
2794 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2795 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002796 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002797 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002798 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002799 PyFile_SetBufSize(p2, 0);
2800
2801 if (n != 4)
2802 CloseHandle(hChildStderrRdDup);
2803
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002804 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002805 Py_XDECREF(p1);
2806 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002807 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002808 break;
2809 }
2810
2811 case POPEN_3:
2812 {
2813 char *m1, *m2;
2814 PyObject *p1, *p2, *p3;
2815
2816 if (mode && _O_TEXT) {
2817 m1 = "r";
2818 m2 = "w";
2819 } else {
2820 m1 = "rb";
2821 m2 = "wb";
2822 }
2823
2824 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2825 f1 = _fdopen(fd1, m2);
2826 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2827 f2 = _fdopen(fd2, m1);
2828 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2829 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002830 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002831 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2832 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002833 PyFile_SetBufSize(p1, 0);
2834 PyFile_SetBufSize(p2, 0);
2835 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002836 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002837 Py_XDECREF(p1);
2838 Py_XDECREF(p2);
2839 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002840 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002841 break;
2842 }
2843 }
2844
2845 if (n == POPEN_4) {
2846 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002847 hChildStdinRd,
2848 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002849 hChildStdoutWr,
2850 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002851 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002852 }
2853 else {
2854 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002855 hChildStdinRd,
2856 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002857 hChildStderrWr,
2858 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002859 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002860 }
2861
Mark Hammondb37a3732000-08-14 04:47:33 +00002862 /*
2863 * Insert the files we've created into the process dictionary
2864 * all referencing the list with the process handle and the
2865 * initial number of files (see description below in _PyPclose).
2866 * Since if _PyPclose later tried to wait on a process when all
2867 * handles weren't closed, it could create a deadlock with the
2868 * child, we spend some energy here to try to ensure that we
2869 * either insert all file handles into the dictionary or none
2870 * at all. It's a little clumsy with the various popen modes
2871 * and variable number of files involved.
2872 */
2873 if (!_PyPopenProcs) {
2874 _PyPopenProcs = PyDict_New();
2875 }
2876
2877 if (_PyPopenProcs) {
2878 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2879 int ins_rc[3];
2880
2881 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2882 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2883
2884 procObj = PyList_New(2);
2885 hProcessObj = PyLong_FromVoidPtr(hProcess);
2886 intObj = PyInt_FromLong(file_count);
2887
2888 if (procObj && hProcessObj && intObj) {
2889 PyList_SetItem(procObj,0,hProcessObj);
2890 PyList_SetItem(procObj,1,intObj);
2891
2892 fileObj[0] = PyLong_FromVoidPtr(f1);
2893 if (fileObj[0]) {
2894 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2895 fileObj[0],
2896 procObj);
2897 }
2898 if (file_count >= 2) {
2899 fileObj[1] = PyLong_FromVoidPtr(f2);
2900 if (fileObj[1]) {
2901 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2902 fileObj[1],
2903 procObj);
2904 }
2905 }
2906 if (file_count >= 3) {
2907 fileObj[2] = PyLong_FromVoidPtr(f3);
2908 if (fileObj[2]) {
2909 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2910 fileObj[2],
2911 procObj);
2912 }
2913 }
2914
2915 if (ins_rc[0] < 0 || !fileObj[0] ||
2916 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2917 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2918 /* Something failed - remove any dictionary
2919 * entries that did make it.
2920 */
2921 if (!ins_rc[0] && fileObj[0]) {
2922 PyDict_DelItem(_PyPopenProcs,
2923 fileObj[0]);
2924 }
2925 if (!ins_rc[1] && fileObj[1]) {
2926 PyDict_DelItem(_PyPopenProcs,
2927 fileObj[1]);
2928 }
2929 if (!ins_rc[2] && fileObj[2]) {
2930 PyDict_DelItem(_PyPopenProcs,
2931 fileObj[2]);
2932 }
2933 }
2934 }
2935
2936 /*
2937 * Clean up our localized references for the dictionary keys
2938 * and value since PyDict_SetItem will Py_INCREF any copies
2939 * that got placed in the dictionary.
2940 */
2941 Py_XDECREF(procObj);
2942 Py_XDECREF(fileObj[0]);
2943 Py_XDECREF(fileObj[1]);
2944 Py_XDECREF(fileObj[2]);
2945 }
2946
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002947 /* Child is launched. Close the parents copy of those pipe
2948 * handles that only the child should have open. You need to
2949 * make sure that no handles to the write end of the output pipe
2950 * are maintained in this process or else the pipe will not close
2951 * when the child process exits and the ReadFile will hang. */
2952
2953 if (!CloseHandle(hChildStdinRd))
2954 return win32_error("CloseHandle", NULL);
2955
2956 if (!CloseHandle(hChildStdoutWr))
2957 return win32_error("CloseHandle", NULL);
2958
2959 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2960 return win32_error("CloseHandle", NULL);
2961
2962 return f;
2963}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002964
2965/*
2966 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2967 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002968 *
2969 * This function uses the _PyPopenProcs dictionary in order to map the
2970 * input file pointer to information about the process that was
2971 * originally created by the popen* call that created the file pointer.
2972 * The dictionary uses the file pointer as a key (with one entry
2973 * inserted for each file returned by the original popen* call) and a
2974 * single list object as the value for all files from a single call.
2975 * The list object contains the Win32 process handle at [0], and a file
2976 * count at [1], which is initialized to the total number of file
2977 * handles using that list.
2978 *
2979 * This function closes whichever handle it is passed, and decrements
2980 * the file count in the dictionary for the process handle pointed to
2981 * by this file. On the last close (when the file count reaches zero),
2982 * this function will wait for the child process and then return its
2983 * exit code as the result of the close() operation. This permits the
2984 * files to be closed in any order - it is always the close() of the
2985 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002986 */
Tim Peters736aa322000-09-01 06:51:24 +00002987
2988 /* RED_FLAG 31-Aug-2000 Tim
2989 * This is always called (today!) between a pair of
2990 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2991 * macros. So the thread running this has no valid thread state, as
2992 * far as Python is concerned. However, this calls some Python API
2993 * functions that cannot be called safely without a valid thread
2994 * state, in particular PyDict_GetItem.
2995 * As a temporary hack (although it may last for years ...), we
2996 * *rely* on not having a valid thread state in this function, in
2997 * order to create our own "from scratch".
2998 * This will deadlock if _PyPclose is ever called by a thread
2999 * holding the global lock.
3000 */
3001
Fredrik Lundh56055a42000-07-23 19:47:12 +00003002static int _PyPclose(FILE *file)
3003{
Fredrik Lundh20318932000-07-26 17:29:12 +00003004 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003005 DWORD exit_code;
3006 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003007 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3008 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003009#ifdef WITH_THREAD
3010 PyInterpreterState* pInterpreterState;
3011 PyThreadState* pThreadState;
3012#endif
3013
Fredrik Lundh20318932000-07-26 17:29:12 +00003014 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003015 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003016 */
3017 result = fclose(file);
3018
Tim Peters736aa322000-09-01 06:51:24 +00003019#ifdef WITH_THREAD
3020 /* Bootstrap a valid thread state into existence. */
3021 pInterpreterState = PyInterpreterState_New();
3022 if (!pInterpreterState) {
3023 /* Well, we're hosed now! We don't have a thread
3024 * state, so can't call a nice error routine, or raise
3025 * an exception. Just die.
3026 */
3027 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003028 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003029 return -1; /* unreachable */
3030 }
3031 pThreadState = PyThreadState_New(pInterpreterState);
3032 if (!pThreadState) {
3033 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003034 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003035 return -1; /* unreachable */
3036 }
3037 /* Grab the global lock. Note that this will deadlock if the
3038 * current thread already has the lock! (see RED_FLAG comments
3039 * before this function)
3040 */
3041 PyEval_RestoreThread(pThreadState);
3042#endif
3043
Fredrik Lundh56055a42000-07-23 19:47:12 +00003044 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003045 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3046 (procObj = PyDict_GetItem(_PyPopenProcs,
3047 fileObj)) != NULL &&
3048 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3049 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3050
3051 hProcess = PyLong_AsVoidPtr(hProcessObj);
3052 file_count = PyInt_AsLong(intObj);
3053
3054 if (file_count > 1) {
3055 /* Still other files referencing process */
3056 file_count--;
3057 PyList_SetItem(procObj,1,
3058 PyInt_FromLong(file_count));
3059 } else {
3060 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003061 if (result != EOF &&
3062 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3063 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003064 /* Possible truncation here in 16-bit environments, but
3065 * real exit codes are just the lower byte in any event.
3066 */
3067 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003068 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003069 /* Indicate failure - this will cause the file object
3070 * to raise an I/O error and translate the last Win32
3071 * error code from errno. We do have a problem with
3072 * last errors that overlap the normal errno table,
3073 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003074 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003075 if (result != EOF) {
3076 /* If the error wasn't from the fclose(), then
3077 * set errno for the file object error handling.
3078 */
3079 errno = GetLastError();
3080 }
3081 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003082 }
3083
3084 /* Free up the native handle at this point */
3085 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003086 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003087
Mark Hammondb37a3732000-08-14 04:47:33 +00003088 /* Remove this file pointer from dictionary */
3089 PyDict_DelItem(_PyPopenProcs, fileObj);
3090
3091 if (PyDict_Size(_PyPopenProcs) == 0) {
3092 Py_DECREF(_PyPopenProcs);
3093 _PyPopenProcs = NULL;
3094 }
3095
3096 } /* if object retrieval ok */
3097
3098 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003099 } /* if _PyPopenProcs */
3100
Tim Peters736aa322000-09-01 06:51:24 +00003101#ifdef WITH_THREAD
3102 /* Tear down the thread & interpreter states.
3103 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003104 * call the thread clear & delete functions, and indeed insist on
3105 * doing that themselves. The lock must be held during the clear, but
3106 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003107 */
3108 PyInterpreterState_Clear(pInterpreterState);
3109 PyEval_ReleaseThread(pThreadState);
3110 PyInterpreterState_Delete(pInterpreterState);
3111#endif
3112
Fredrik Lundh56055a42000-07-23 19:47:12 +00003113 return result;
3114}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003115
3116#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003118posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003119{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003120 char *name;
3121 char *mode = "r";
3122 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003123 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003124 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003125 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003126 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003127 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003128 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003129 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003130 if (fp == NULL)
3131 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003132 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003133 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003134 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003135 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003136}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003137#endif
3138
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003139#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003140
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003141
Guido van Rossumb6775db1994-08-01 11:34:53 +00003142#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003143static char posix_setuid__doc__[] =
3144"setuid(uid) -> None\n\
3145Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003147posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003148{
3149 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003150 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003151 return NULL;
3152 if (setuid(uid) < 0)
3153 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003154 Py_INCREF(Py_None);
3155 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003156}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003157#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003159
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003160#ifdef HAVE_SETEUID
3161static char posix_seteuid__doc__[] =
3162"seteuid(uid) -> None\n\
3163Set the current process's effective user id.";
3164static PyObject *
3165posix_seteuid (PyObject *self, PyObject *args)
3166{
3167 int euid;
3168 if (!PyArg_ParseTuple(args, "i", &euid)) {
3169 return NULL;
3170 } else if (seteuid(euid) < 0) {
3171 return posix_error();
3172 } else {
3173 Py_INCREF(Py_None);
3174 return Py_None;
3175 }
3176}
3177#endif /* HAVE_SETEUID */
3178
3179#ifdef HAVE_SETEGID
3180static char posix_setegid__doc__[] =
3181"setegid(gid) -> None\n\
3182Set the current process's effective group id.";
3183static PyObject *
3184posix_setegid (PyObject *self, PyObject *args)
3185{
3186 int egid;
3187 if (!PyArg_ParseTuple(args, "i", &egid)) {
3188 return NULL;
3189 } else if (setegid(egid) < 0) {
3190 return posix_error();
3191 } else {
3192 Py_INCREF(Py_None);
3193 return Py_None;
3194 }
3195}
3196#endif /* HAVE_SETEGID */
3197
3198#ifdef HAVE_SETREUID
3199static char posix_setreuid__doc__[] =
3200"seteuid(ruid, euid) -> None\n\
3201Set the current process's real and effective user ids.";
3202static PyObject *
3203posix_setreuid (PyObject *self, PyObject *args)
3204{
3205 int ruid, euid;
3206 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3207 return NULL;
3208 } else if (setreuid(ruid, euid) < 0) {
3209 return posix_error();
3210 } else {
3211 Py_INCREF(Py_None);
3212 return Py_None;
3213 }
3214}
3215#endif /* HAVE_SETREUID */
3216
3217#ifdef HAVE_SETREGID
3218static char posix_setregid__doc__[] =
3219"setegid(rgid, egid) -> None\n\
3220Set the current process's real and effective group ids.";
3221static PyObject *
3222posix_setregid (PyObject *self, PyObject *args)
3223{
3224 int rgid, egid;
3225 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3226 return NULL;
3227 } else if (setregid(rgid, egid) < 0) {
3228 return posix_error();
3229 } else {
3230 Py_INCREF(Py_None);
3231 return Py_None;
3232 }
3233}
3234#endif /* HAVE_SETREGID */
3235
Guido van Rossumb6775db1994-08-01 11:34:53 +00003236#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003237static char posix_setgid__doc__[] =
3238"setgid(gid) -> None\n\
3239Set the current process's group id.";
3240
Barry Warsaw53699e91996-12-10 23:23:01 +00003241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003242posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003243{
3244 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003245 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003246 return NULL;
3247 if (setgid(gid) < 0)
3248 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003249 Py_INCREF(Py_None);
3250 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003251}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003252#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003253
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003254#ifdef HAVE_SETGROUPS
3255static char posix_setgroups__doc__[] =
3256"setgroups(list) -> None\n\
3257Set the groups of the current process to list.";
3258
3259static PyObject *
3260posix_setgroups(PyObject *self, PyObject *args)
3261{
3262 PyObject *groups;
3263 int i, len;
3264 gid_t grouplist[MAX_GROUPS];
3265
3266 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3267 return NULL;
3268 if (!PySequence_Check(groups)) {
3269 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3270 return NULL;
3271 }
3272 len = PySequence_Size(groups);
3273 if (len > MAX_GROUPS) {
3274 PyErr_SetString(PyExc_ValueError, "too many groups");
3275 return NULL;
3276 }
3277 for(i = 0; i < len; i++) {
3278 PyObject *elem;
3279 elem = PySequence_GetItem(groups, i);
3280 if (!elem)
3281 return NULL;
3282 if (!PyInt_Check(elem)) {
3283 PyErr_SetString(PyExc_TypeError,
3284 "groups must be integers");
3285 Py_DECREF(elem);
3286 return NULL;
3287 }
3288 /* XXX: check that value fits into gid_t. */
3289 grouplist[i] = PyInt_AsLong(elem);
3290 Py_DECREF(elem);
3291 }
3292
3293 if (setgroups(len, grouplist) < 0)
3294 return posix_error();
3295 Py_INCREF(Py_None);
3296 return Py_None;
3297}
3298#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003299
Guido van Rossumb6775db1994-08-01 11:34:53 +00003300#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003301static char posix_waitpid__doc__[] =
3302"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003303Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003304
Barry Warsaw53699e91996-12-10 23:23:01 +00003305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003306posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003307{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003308 int pid, options;
3309#ifdef UNION_WAIT
3310 union wait status;
3311#define status_i (status.w_status)
3312#else
3313 int status;
3314#define status_i status
3315#endif
3316 status_i = 0;
3317
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003318 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003319 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003320 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003321#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003322 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003323#else
3324 pid = waitpid(pid, &status, options);
3325#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003326 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003327 if (pid == -1)
3328 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003329 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003330 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003331}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003332#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003334
Guido van Rossumad0ee831995-03-01 10:34:45 +00003335#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003336static char posix_wait__doc__[] =
3337"wait() -> (pid, status)\n\
3338Wait for completion of a child process.";
3339
Barry Warsaw53699e91996-12-10 23:23:01 +00003340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003341posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003342{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003343 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003344#ifdef UNION_WAIT
3345 union wait status;
3346#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003347#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003348 int status;
3349#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003350#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003351 if (!PyArg_ParseTuple(args, ":wait"))
3352 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003353 status_i = 0;
3354 Py_BEGIN_ALLOW_THREADS
3355 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003356 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003357 if (pid == -1)
3358 return posix_error();
3359 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003360 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003361#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003362}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003363#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003365
3366static char posix_lstat__doc__[] =
3367"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3368Like stat(path), but do not follow symbolic links.";
3369
Barry Warsaw53699e91996-12-10 23:23:01 +00003370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003371posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003372{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003373#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003374 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003375#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003376 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003377#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003378}
3379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003380
Guido van Rossumb6775db1994-08-01 11:34:53 +00003381#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003382static char posix_readlink__doc__[] =
3383"readlink(path) -> path\n\
3384Return a string representing the path to which the symbolic link points.";
3385
Barry Warsaw53699e91996-12-10 23:23:01 +00003386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003387posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003388{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003389 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003390 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003391 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003392 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003393 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003394 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003395 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003396 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003397 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003398 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003399 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003400}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003401#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003402
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003403
Guido van Rossumb6775db1994-08-01 11:34:53 +00003404#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003405static char posix_symlink__doc__[] =
3406"symlink(src, dst) -> None\n\
3407Create a symbolic link.";
3408
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003409static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003410posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003411{
Mark Hammondef8b6542001-05-13 08:04:26 +00003412 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003413}
3414#endif /* HAVE_SYMLINK */
3415
3416
3417#ifdef HAVE_TIMES
3418#ifndef HZ
3419#define HZ 60 /* Universal constant :-) */
3420#endif /* HZ */
3421
Guido van Rossumd48f2521997-12-05 22:19:34 +00003422#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3423static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003424system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003425{
3426 ULONG value = 0;
3427
3428 Py_BEGIN_ALLOW_THREADS
3429 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3430 Py_END_ALLOW_THREADS
3431
3432 return value;
3433}
3434
3435static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003436posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003437{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003438 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003439 return NULL;
3440
3441 /* Currently Only Uptime is Provided -- Others Later */
3442 return Py_BuildValue("ddddd",
3443 (double)0 /* t.tms_utime / HZ */,
3444 (double)0 /* t.tms_stime / HZ */,
3445 (double)0 /* t.tms_cutime / HZ */,
3446 (double)0 /* t.tms_cstime / HZ */,
3447 (double)system_uptime() / 1000);
3448}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003449#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003450static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003451posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003452{
3453 struct tms t;
3454 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003455 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003456 return NULL;
3457 errno = 0;
3458 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003459 if (c == (clock_t) -1)
3460 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003461 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003462 (double)t.tms_utime / HZ,
3463 (double)t.tms_stime / HZ,
3464 (double)t.tms_cutime / HZ,
3465 (double)t.tms_cstime / HZ,
3466 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003467}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003468#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003469#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003470
3471
Guido van Rossum87755a21996-09-07 00:59:43 +00003472#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003473#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003474static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003475posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003476{
3477 FILETIME create, exit, kernel, user;
3478 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003479 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003480 return NULL;
3481 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003482 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3483 /* The fields of a FILETIME structure are the hi and lo part
3484 of a 64-bit value expressed in 100 nanosecond units.
3485 1e7 is one second in such units; 1e-7 the inverse.
3486 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3487 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003488 return Py_BuildValue(
3489 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003490 (double)(kernel.dwHighDateTime*429.4967296 +
3491 kernel.dwLowDateTime*1e-7),
3492 (double)(user.dwHighDateTime*429.4967296 +
3493 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003494 (double)0,
3495 (double)0,
3496 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003497}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003498#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003499
3500#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003501static char posix_times__doc__[] =
3502"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3503Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003504#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003505
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003506
Guido van Rossumb6775db1994-08-01 11:34:53 +00003507#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003508static char posix_setsid__doc__[] =
3509"setsid() -> None\n\
3510Call the system call setsid().";
3511
Barry Warsaw53699e91996-12-10 23:23:01 +00003512static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003513posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003514{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003515 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003516 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003517 if (setsid() < 0)
3518 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003519 Py_INCREF(Py_None);
3520 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003521}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003522#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003523
Guido van Rossumb6775db1994-08-01 11:34:53 +00003524#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003525static char posix_setpgid__doc__[] =
3526"setpgid(pid, pgrp) -> None\n\
3527Call the system call setpgid().";
3528
Barry Warsaw53699e91996-12-10 23:23:01 +00003529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003530posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003531{
3532 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003533 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003534 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003535 if (setpgid(pid, pgrp) < 0)
3536 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003537 Py_INCREF(Py_None);
3538 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003539}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003540#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003541
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003542
Guido van Rossumb6775db1994-08-01 11:34:53 +00003543#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003544static char posix_tcgetpgrp__doc__[] =
3545"tcgetpgrp(fd) -> pgid\n\
3546Return the process group associated with the terminal given by a fd.";
3547
Barry Warsaw53699e91996-12-10 23:23:01 +00003548static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003549posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003550{
3551 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003552 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003553 return NULL;
3554 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003555 if (pgid < 0)
3556 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003557 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003558}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003559#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003560
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003561
Guido van Rossumb6775db1994-08-01 11:34:53 +00003562#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003563static char posix_tcsetpgrp__doc__[] =
3564"tcsetpgrp(fd, pgid) -> None\n\
3565Set the process group associated with the terminal given by a fd.";
3566
Barry Warsaw53699e91996-12-10 23:23:01 +00003567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003568posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003569{
3570 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003571 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003572 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003573 if (tcsetpgrp(fd, pgid) < 0)
3574 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003575 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003576 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003577}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003578#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003579
Guido van Rossum687dd131993-05-17 08:34:16 +00003580/* Functions acting on file descriptors */
3581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003582static char posix_open__doc__[] =
3583"open(filename, flag [, mode=0777]) -> fd\n\
3584Open a file (for low level IO).";
3585
Barry Warsaw53699e91996-12-10 23:23:01 +00003586static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003587posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003588{
Mark Hammondef8b6542001-05-13 08:04:26 +00003589 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003590 int flag;
3591 int mode = 0777;
3592 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003593 if (!PyArg_ParseTuple(args, "eti|i",
3594 Py_FileSystemDefaultEncoding, &file,
3595 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003596 return NULL;
3597
Barry Warsaw53699e91996-12-10 23:23:01 +00003598 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003599 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003600 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003601 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003602 return posix_error_with_allocated_filename(file);
3603 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003604 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003605}
3606
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003607
3608static char posix_close__doc__[] =
3609"close(fd) -> None\n\
3610Close a file descriptor (for low level IO).";
3611
Barry Warsaw53699e91996-12-10 23:23:01 +00003612static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003613posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003614{
3615 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003616 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003617 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003618 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003619 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003620 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003621 if (res < 0)
3622 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003623 Py_INCREF(Py_None);
3624 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003625}
3626
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003627
3628static char posix_dup__doc__[] =
3629"dup(fd) -> fd2\n\
3630Return a duplicate of a file descriptor.";
3631
Barry Warsaw53699e91996-12-10 23:23:01 +00003632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003633posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003634{
3635 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003636 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003637 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003638 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003639 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003640 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003641 if (fd < 0)
3642 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003643 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003644}
3645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003646
3647static char posix_dup2__doc__[] =
3648"dup2(fd, fd2) -> None\n\
3649Duplicate file descriptor.";
3650
Barry Warsaw53699e91996-12-10 23:23:01 +00003651static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003652posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003653{
3654 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003655 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003656 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003657 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003658 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003659 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003660 if (res < 0)
3661 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003662 Py_INCREF(Py_None);
3663 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003664}
3665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003666
3667static char posix_lseek__doc__[] =
3668"lseek(fd, pos, how) -> newpos\n\
3669Set the current position of a file descriptor.";
3670
Barry Warsaw53699e91996-12-10 23:23:01 +00003671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003672posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003673{
3674 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003675#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003676 LONG_LONG pos, res;
3677#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003678 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003679#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003680 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003681 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003682 return NULL;
3683#ifdef SEEK_SET
3684 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3685 switch (how) {
3686 case 0: how = SEEK_SET; break;
3687 case 1: how = SEEK_CUR; break;
3688 case 2: how = SEEK_END; break;
3689 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003690#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003691
3692#if !defined(HAVE_LARGEFILE_SUPPORT)
3693 pos = PyInt_AsLong(posobj);
3694#else
3695 pos = PyLong_Check(posobj) ?
3696 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3697#endif
3698 if (PyErr_Occurred())
3699 return NULL;
3700
Barry Warsaw53699e91996-12-10 23:23:01 +00003701 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003702#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003703 res = _lseeki64(fd, pos, how);
3704#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003705 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003706#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003707 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003708 if (res < 0)
3709 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003710
3711#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003712 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003713#else
3714 return PyLong_FromLongLong(res);
3715#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003716}
3717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003718
3719static char posix_read__doc__[] =
3720"read(fd, buffersize) -> string\n\
3721Read a file descriptor.";
3722
Barry Warsaw53699e91996-12-10 23:23:01 +00003723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003724posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003725{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003726 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003727 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003728 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003729 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003730 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003731 if (buffer == NULL)
3732 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003733 Py_BEGIN_ALLOW_THREADS
3734 n = read(fd, PyString_AsString(buffer), size);
3735 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003736 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003737 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003738 return posix_error();
3739 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003740 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003741 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003742 return buffer;
3743}
3744
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003745
3746static char posix_write__doc__[] =
3747"write(fd, string) -> byteswritten\n\
3748Write a string to a file descriptor.";
3749
Barry Warsaw53699e91996-12-10 23:23:01 +00003750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003751posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003752{
3753 int fd, size;
3754 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003755 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003756 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003757 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003758 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003759 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003760 if (size < 0)
3761 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003762 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003763}
3764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003765
3766static char posix_fstat__doc__[]=
3767"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3768Like stat(), but for an open file descriptor.";
3769
Barry Warsaw53699e91996-12-10 23:23:01 +00003770static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003771posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003772{
3773 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003774 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003775 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003776 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003777 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003778 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003779 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003780 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003781 if (res != 0)
3782 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003783
3784 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003785}
3786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003787
3788static char posix_fdopen__doc__[] =
3789"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3790Return an open file object connected to a file descriptor.";
3791
Barry Warsaw53699e91996-12-10 23:23:01 +00003792static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003793posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003794{
Guido van Rossum687dd131993-05-17 08:34:16 +00003795 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003796 char *mode = "r";
3797 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003798 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003799 PyObject *f;
3800 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003801 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003802
Barry Warsaw53699e91996-12-10 23:23:01 +00003803 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003804 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003805 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003806 if (fp == NULL)
3807 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003808 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003809 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003810 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003811 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003812}
3813
Skip Montanaro1517d842000-07-19 14:34:14 +00003814static char posix_isatty__doc__[] =
3815"isatty(fd) -> Boolean\n\
3816Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003817connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003818
3819static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003820posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003821{
3822 int fd;
3823 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3824 return NULL;
3825 return Py_BuildValue("i", isatty(fd));
3826}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003827
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003828#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003829static char posix_pipe__doc__[] =
3830"pipe() -> (read_end, write_end)\n\
3831Create a pipe.";
3832
Barry Warsaw53699e91996-12-10 23:23:01 +00003833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003834posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003835{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003836#if defined(PYOS_OS2)
3837 HFILE read, write;
3838 APIRET rc;
3839
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003840 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003841 return NULL;
3842
3843 Py_BEGIN_ALLOW_THREADS
3844 rc = DosCreatePipe( &read, &write, 4096);
3845 Py_END_ALLOW_THREADS
3846 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003847 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003848
3849 return Py_BuildValue("(ii)", read, write);
3850#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003851#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003852 int fds[2];
3853 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003854 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003855 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003856 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003857 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003858 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003859 if (res != 0)
3860 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003861 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003862#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003863 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003864 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003865 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003866 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003867 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003868 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003869 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003870 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003871 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003872 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003873 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3874 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003875 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003876#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003877#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003878}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003879#endif /* HAVE_PIPE */
3880
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003881
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003882#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003883static char posix_mkfifo__doc__[] =
3884"mkfifo(file, [, mode=0666]) -> None\n\
3885Create a FIFO (a POSIX named pipe).";
3886
Barry Warsaw53699e91996-12-10 23:23:01 +00003887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003888posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003889{
3890 char *file;
3891 int mode = 0666;
3892 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003893 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003894 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003895 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003896 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003897 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003898 if (res < 0)
3899 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003900 Py_INCREF(Py_None);
3901 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003902}
3903#endif
3904
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003905
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003906#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003907static char posix_ftruncate__doc__[] =
3908"ftruncate(fd, length) -> None\n\
3909Truncate a file to a specified length.";
3910
Barry Warsaw53699e91996-12-10 23:23:01 +00003911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003912posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003913{
3914 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003915 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003916 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003917 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003918
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003919 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003920 return NULL;
3921
3922#if !defined(HAVE_LARGEFILE_SUPPORT)
3923 length = PyInt_AsLong(lenobj);
3924#else
3925 length = PyLong_Check(lenobj) ?
3926 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3927#endif
3928 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003929 return NULL;
3930
Barry Warsaw53699e91996-12-10 23:23:01 +00003931 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003932 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003933 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003934 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003935 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003936 return NULL;
3937 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003938 Py_INCREF(Py_None);
3939 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003940}
3941#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003942
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003943#ifdef NeXT
3944#define HAVE_PUTENV
3945/* Steve Spicklemire got this putenv from NeXTAnswers */
3946static int
3947putenv(char *newval)
3948{
3949 extern char **environ;
3950
3951 static int firstTime = 1;
3952 char **ep;
3953 char *cp;
3954 int esiz;
3955 char *np;
3956
3957 if (!(np = strchr(newval, '=')))
3958 return 1;
3959 *np = '\0';
3960
3961 /* look it up */
3962 for (ep=environ ; *ep ; ep++)
3963 {
3964 /* this should always be true... */
3965 if (cp = strchr(*ep, '='))
3966 {
3967 *cp = '\0';
3968 if (!strcmp(*ep, newval))
3969 {
3970 /* got it! */
3971 *cp = '=';
3972 break;
3973 }
3974 *cp = '=';
3975 }
3976 else
3977 {
3978 *np = '=';
3979 return 1;
3980 }
3981 }
3982
3983 *np = '=';
3984 if (*ep)
3985 {
3986 /* the string was already there:
3987 just replace it with the new one */
3988 *ep = newval;
3989 return 0;
3990 }
3991
3992 /* expand environ by one */
3993 for (esiz=2, ep=environ ; *ep ; ep++)
3994 esiz++;
3995 if (firstTime)
3996 {
3997 char **epp;
3998 char **newenv;
3999 if (!(newenv = malloc(esiz * sizeof(char *))))
4000 return 1;
4001
4002 for (ep=environ, epp=newenv ; *ep ;)
4003 *epp++ = *ep++;
4004 *epp++ = newval;
4005 *epp = (char *) 0;
4006 environ = newenv;
4007 }
4008 else
4009 {
4010 if (!(environ = realloc(environ, esiz * sizeof(char *))))
4011 return 1;
4012 environ[esiz - 2] = newval;
4013 environ[esiz - 1] = (char *) 0;
4014 firstTime = 0;
4015 }
4016
4017 return 0;
4018}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00004019#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004020
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004021
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004022#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004023static char posix_putenv__doc__[] =
4024"putenv(key, value) -> None\n\
4025Change or add an environment variable.";
4026
Fred Drake762e2061999-08-26 17:23:54 +00004027/* Save putenv() parameters as values here, so we can collect them when they
4028 * get re-set with another call for the same key. */
4029static PyObject *posix_putenv_garbage;
4030
Barry Warsaw53699e91996-12-10 23:23:01 +00004031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004032posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004033{
4034 char *s1, *s2;
4035 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004036 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004037 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004038
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004039 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004040 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004041
4042#if defined(PYOS_OS2)
4043 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4044 APIRET rc;
4045
4046 if (strlen(s2) == 0) /* If New Value is an Empty String */
4047 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4048
4049 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4050 if (rc != NO_ERROR)
4051 return os2_error(rc);
4052
4053 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4054 APIRET rc;
4055
4056 if (strlen(s2) == 0) /* If New Value is an Empty String */
4057 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4058
4059 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4060 if (rc != NO_ERROR)
4061 return os2_error(rc);
4062 } else {
4063#endif
4064
Fred Drake762e2061999-08-26 17:23:54 +00004065 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004066 len = strlen(s1) + strlen(s2) + 2;
4067 /* len includes space for a trailing \0; the size arg to
4068 PyString_FromStringAndSize does not count that */
4069 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004070 if (newstr == NULL)
4071 return PyErr_NoMemory();
4072 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004073 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004074 if (putenv(new)) {
4075 posix_error();
4076 return NULL;
4077 }
Fred Drake762e2061999-08-26 17:23:54 +00004078 /* Install the first arg and newstr in posix_putenv_garbage;
4079 * this will cause previous value to be collected. This has to
4080 * happen after the real putenv() call because the old value
4081 * was still accessible until then. */
4082 if (PyDict_SetItem(posix_putenv_garbage,
4083 PyTuple_GET_ITEM(args, 0), newstr)) {
4084 /* really not much we can do; just leak */
4085 PyErr_Clear();
4086 }
4087 else {
4088 Py_DECREF(newstr);
4089 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004090
4091#if defined(PYOS_OS2)
4092 }
4093#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004094 Py_INCREF(Py_None);
4095 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004096}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004097#endif /* putenv */
4098
Guido van Rossumc524d952001-10-19 01:31:59 +00004099#ifdef HAVE_UNSETENV
4100static char posix_unsetenv__doc__[] =
4101"unsetenv(key) -> None\n\
4102Delete an environment variable.";
4103
4104static PyObject *
4105posix_unsetenv(PyObject *self, PyObject *args)
4106{
4107 char *s1;
4108
4109 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4110 return NULL;
4111
4112 unsetenv(s1);
4113
4114 /* Remove the key from posix_putenv_garbage;
4115 * this will cause it to be collected. This has to
4116 * happen after the real unsetenv() call because the
4117 * old value was still accessible until then.
4118 */
4119 if (PyDict_DelItem(posix_putenv_garbage,
4120 PyTuple_GET_ITEM(args, 0))) {
4121 /* really not much we can do; just leak */
4122 PyErr_Clear();
4123 }
4124
4125 Py_INCREF(Py_None);
4126 return Py_None;
4127}
4128#endif /* unsetenv */
4129
Guido van Rossumb6a47161997-09-15 22:54:34 +00004130#ifdef HAVE_STRERROR
4131static char posix_strerror__doc__[] =
4132"strerror(code) -> string\n\
4133Translate an error code to a message string.";
4134
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004136posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004137{
4138 int code;
4139 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004140 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004141 return NULL;
4142 message = strerror(code);
4143 if (message == NULL) {
4144 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004145 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004146 return NULL;
4147 }
4148 return PyString_FromString(message);
4149}
4150#endif /* strerror */
4151
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004152
Guido van Rossumc9641791998-08-04 15:26:23 +00004153#ifdef HAVE_SYS_WAIT_H
4154
4155#ifdef WIFSTOPPED
4156static char posix_WIFSTOPPED__doc__[] =
4157"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004158Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004159
4160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004161posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004162{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004163#ifdef UNION_WAIT
4164 union wait status;
4165#define status_i (status.w_status)
4166#else
4167 int status;
4168#define status_i status
4169#endif
4170 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004171
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004172 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004173 {
4174 return NULL;
4175 }
4176
4177 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004178#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004179}
4180#endif /* WIFSTOPPED */
4181
4182#ifdef WIFSIGNALED
4183static char posix_WIFSIGNALED__doc__[] =
4184"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004185Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004186
4187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004188posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004189{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004190#ifdef UNION_WAIT
4191 union wait status;
4192#define status_i (status.w_status)
4193#else
4194 int status;
4195#define status_i status
4196#endif
4197 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004198
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004199 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004200 {
4201 return NULL;
4202 }
4203
4204 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004205#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004206}
4207#endif /* WIFSIGNALED */
4208
4209#ifdef WIFEXITED
4210static char posix_WIFEXITED__doc__[] =
4211"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004212Return true if the process returning 'status' exited using the exit()\n\
4213system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004214
4215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004216posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004217{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004218#ifdef UNION_WAIT
4219 union wait status;
4220#define status_i (status.w_status)
4221#else
4222 int status;
4223#define status_i status
4224#endif
4225 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004226
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004227 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004228 {
4229 return NULL;
4230 }
4231
4232 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004233#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004234}
4235#endif /* WIFEXITED */
4236
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004237#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004238static char posix_WEXITSTATUS__doc__[] =
4239"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004240Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004241
4242static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004243posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004244{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004245#ifdef UNION_WAIT
4246 union wait status;
4247#define status_i (status.w_status)
4248#else
4249 int status;
4250#define status_i status
4251#endif
4252 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004253
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004254 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004255 {
4256 return NULL;
4257 }
4258
4259 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004260#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004261}
4262#endif /* WEXITSTATUS */
4263
4264#ifdef WTERMSIG
4265static char posix_WTERMSIG__doc__[] =
4266"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004267Return the signal that terminated the process that provided the 'status'\n\
4268value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004269
4270static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004271posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004272{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004273#ifdef UNION_WAIT
4274 union wait status;
4275#define status_i (status.w_status)
4276#else
4277 int status;
4278#define status_i status
4279#endif
4280 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004281
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004282 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004283 {
4284 return NULL;
4285 }
4286
4287 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004288#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004289}
4290#endif /* WTERMSIG */
4291
4292#ifdef WSTOPSIG
4293static char posix_WSTOPSIG__doc__[] =
4294"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004295Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004296
4297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004298posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004299{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004300#ifdef UNION_WAIT
4301 union wait status;
4302#define status_i (status.w_status)
4303#else
4304 int status;
4305#define status_i status
4306#endif
4307 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004308
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004309 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004310 {
4311 return NULL;
4312 }
4313
4314 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004315#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004316}
4317#endif /* WSTOPSIG */
4318
4319#endif /* HAVE_SYS_WAIT_H */
4320
4321
Guido van Rossum94f6f721999-01-06 18:42:14 +00004322#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004323#ifdef _SCO_DS
4324/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4325 needed definitions in sys/statvfs.h */
4326#define _SVID3
4327#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004328#include <sys/statvfs.h>
4329
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004330static PyObject*
4331_pystatvfs_fromstructstatvfs(struct statvfs st) {
4332 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4333 if (v == NULL)
4334 return NULL;
4335
4336#if !defined(HAVE_LARGEFILE_SUPPORT)
4337 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4338 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4339 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4340 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4341 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4342 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4343 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4344 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4345 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4346 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4347#else
4348 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4349 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4350 PyStructSequence_SET_ITEM(v, 2,
4351 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
4352 PyStructSequence_SET_ITEM(v, 3,
4353 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4354 PyStructSequence_SET_ITEM(v, 4,
4355 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
4356 PyStructSequence_SET_ITEM(v, 5,
4357 PyLong_FromLongLong((LONG_LONG) st.f_files));
4358 PyStructSequence_SET_ITEM(v, 6,
4359 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
4360 PyStructSequence_SET_ITEM(v, 7,
4361 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4362 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4363 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4364#endif
4365
4366 return v;
4367}
4368
Guido van Rossum94f6f721999-01-06 18:42:14 +00004369static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004370"fstatvfs(fd) -> \n\
4371 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004372Perform an fstatvfs system call on the given fd.";
4373
4374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004375posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004376{
4377 int fd, res;
4378 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004379
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004380 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004381 return NULL;
4382 Py_BEGIN_ALLOW_THREADS
4383 res = fstatvfs(fd, &st);
4384 Py_END_ALLOW_THREADS
4385 if (res != 0)
4386 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004387
4388 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004389}
4390#endif /* HAVE_FSTATVFS */
4391
4392
4393#if defined(HAVE_STATVFS)
4394#include <sys/statvfs.h>
4395
4396static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004397"statvfs(path) -> \n\
4398 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004399Perform a statvfs system call on the given path.";
4400
4401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004402posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004403{
4404 char *path;
4405 int res;
4406 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004407 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004408 return NULL;
4409 Py_BEGIN_ALLOW_THREADS
4410 res = statvfs(path, &st);
4411 Py_END_ALLOW_THREADS
4412 if (res != 0)
4413 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004414
4415 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004416}
4417#endif /* HAVE_STATVFS */
4418
4419
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004420#ifdef HAVE_TEMPNAM
4421static char posix_tempnam__doc__[] = "\
4422tempnam([dir[, prefix]]) -> string\n\
4423Return a unique name for a temporary file.\n\
4424The directory and a short may be specified as strings; they may be omitted\n\
4425or None if not needed.";
4426
4427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004428posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004429{
4430 PyObject *result = NULL;
4431 char *dir = NULL;
4432 char *pfx = NULL;
4433 char *name;
4434
4435 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4436 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004437
4438 if (PyErr_Warn(PyExc_RuntimeWarning,
4439 "tempnam is a potential security risk to your program") < 0)
4440 return NULL;
4441
Fred Drake78b71c22001-07-17 20:37:36 +00004442#ifdef MS_WIN32
4443 name = _tempnam(dir, pfx);
4444#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004445 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004446#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004447 if (name == NULL)
4448 return PyErr_NoMemory();
4449 result = PyString_FromString(name);
4450 free(name);
4451 return result;
4452}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004453#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004454
4455
4456#ifdef HAVE_TMPFILE
4457static char posix_tmpfile__doc__[] = "\
4458tmpfile() -> file object\n\
4459Create a temporary file with no directory entries.";
4460
4461static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004462posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004463{
4464 FILE *fp;
4465
4466 if (!PyArg_ParseTuple(args, ":tmpfile"))
4467 return NULL;
4468 fp = tmpfile();
4469 if (fp == NULL)
4470 return posix_error();
4471 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4472}
4473#endif
4474
4475
4476#ifdef HAVE_TMPNAM
4477static char posix_tmpnam__doc__[] = "\
4478tmpnam() -> string\n\
4479Return a unique name for a temporary file.";
4480
4481static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004482posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004483{
4484 char buffer[L_tmpnam];
4485 char *name;
4486
4487 if (!PyArg_ParseTuple(args, ":tmpnam"))
4488 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004489
4490 if (PyErr_Warn(PyExc_RuntimeWarning,
4491 "tmpnam is a potential security risk to your program") < 0)
4492 return NULL;
4493
Greg Wardb48bc172000-03-01 21:51:56 +00004494#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004495 name = tmpnam_r(buffer);
4496#else
4497 name = tmpnam(buffer);
4498#endif
4499 if (name == NULL) {
4500 PyErr_SetObject(PyExc_OSError,
4501 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004502#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004503 "unexpected NULL from tmpnam_r"
4504#else
4505 "unexpected NULL from tmpnam"
4506#endif
4507 ));
4508 return NULL;
4509 }
4510 return PyString_FromString(buffer);
4511}
4512#endif
4513
4514
Fred Drakec9680921999-12-13 16:37:25 +00004515/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4516 * It maps strings representing configuration variable names to
4517 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004518 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004519 * rarely-used constants. There are three separate tables that use
4520 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004521 *
4522 * This code is always included, even if none of the interfaces that
4523 * need it are included. The #if hackery needed to avoid it would be
4524 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004525 */
4526struct constdef {
4527 char *name;
4528 long value;
4529};
4530
Fred Drake12c6e2d1999-12-14 21:25:03 +00004531static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004532conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4533 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004534{
4535 if (PyInt_Check(arg)) {
4536 *valuep = PyInt_AS_LONG(arg);
4537 return 1;
4538 }
4539 if (PyString_Check(arg)) {
4540 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004541 size_t lo = 0;
4542 size_t mid;
4543 size_t hi = tablesize;
4544 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004545 char *confname = PyString_AS_STRING(arg);
4546 while (lo < hi) {
4547 mid = (lo + hi) / 2;
4548 cmp = strcmp(confname, table[mid].name);
4549 if (cmp < 0)
4550 hi = mid;
4551 else if (cmp > 0)
4552 lo = mid + 1;
4553 else {
4554 *valuep = table[mid].value;
4555 return 1;
4556 }
4557 }
4558 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4559 }
4560 else
4561 PyErr_SetString(PyExc_TypeError,
4562 "configuration names must be strings or integers");
4563 return 0;
4564}
4565
4566
4567#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4568static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004569#ifdef _PC_ABI_AIO_XFER_MAX
4570 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4571#endif
4572#ifdef _PC_ABI_ASYNC_IO
4573 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4574#endif
Fred Drakec9680921999-12-13 16:37:25 +00004575#ifdef _PC_ASYNC_IO
4576 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4577#endif
4578#ifdef _PC_CHOWN_RESTRICTED
4579 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4580#endif
4581#ifdef _PC_FILESIZEBITS
4582 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4583#endif
4584#ifdef _PC_LAST
4585 {"PC_LAST", _PC_LAST},
4586#endif
4587#ifdef _PC_LINK_MAX
4588 {"PC_LINK_MAX", _PC_LINK_MAX},
4589#endif
4590#ifdef _PC_MAX_CANON
4591 {"PC_MAX_CANON", _PC_MAX_CANON},
4592#endif
4593#ifdef _PC_MAX_INPUT
4594 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4595#endif
4596#ifdef _PC_NAME_MAX
4597 {"PC_NAME_MAX", _PC_NAME_MAX},
4598#endif
4599#ifdef _PC_NO_TRUNC
4600 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4601#endif
4602#ifdef _PC_PATH_MAX
4603 {"PC_PATH_MAX", _PC_PATH_MAX},
4604#endif
4605#ifdef _PC_PIPE_BUF
4606 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4607#endif
4608#ifdef _PC_PRIO_IO
4609 {"PC_PRIO_IO", _PC_PRIO_IO},
4610#endif
4611#ifdef _PC_SOCK_MAXBUF
4612 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4613#endif
4614#ifdef _PC_SYNC_IO
4615 {"PC_SYNC_IO", _PC_SYNC_IO},
4616#endif
4617#ifdef _PC_VDISABLE
4618 {"PC_VDISABLE", _PC_VDISABLE},
4619#endif
4620};
4621
Fred Drakec9680921999-12-13 16:37:25 +00004622static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004623conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004624{
4625 return conv_confname(arg, valuep, posix_constants_pathconf,
4626 sizeof(posix_constants_pathconf)
4627 / sizeof(struct constdef));
4628}
4629#endif
4630
4631#ifdef HAVE_FPATHCONF
4632static char posix_fpathconf__doc__[] = "\
4633fpathconf(fd, name) -> integer\n\
4634Return the configuration limit name for the file descriptor fd.\n\
4635If there is no limit, return -1.";
4636
4637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004638posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004639{
4640 PyObject *result = NULL;
4641 int name, fd;
4642
Fred Drake12c6e2d1999-12-14 21:25:03 +00004643 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4644 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004645 long limit;
4646
4647 errno = 0;
4648 limit = fpathconf(fd, name);
4649 if (limit == -1 && errno != 0)
4650 posix_error();
4651 else
4652 result = PyInt_FromLong(limit);
4653 }
4654 return result;
4655}
4656#endif
4657
4658
4659#ifdef HAVE_PATHCONF
4660static char posix_pathconf__doc__[] = "\
4661pathconf(path, name) -> integer\n\
4662Return the configuration limit name for the file or directory path.\n\
4663If there is no limit, return -1.";
4664
4665static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004666posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004667{
4668 PyObject *result = NULL;
4669 int name;
4670 char *path;
4671
4672 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4673 conv_path_confname, &name)) {
4674 long limit;
4675
4676 errno = 0;
4677 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004678 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004679 if (errno == EINVAL)
4680 /* could be a path or name problem */
4681 posix_error();
4682 else
4683 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004684 }
Fred Drakec9680921999-12-13 16:37:25 +00004685 else
4686 result = PyInt_FromLong(limit);
4687 }
4688 return result;
4689}
4690#endif
4691
4692#ifdef HAVE_CONFSTR
4693static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004694#ifdef _CS_ARCHITECTURE
4695 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4696#endif
4697#ifdef _CS_HOSTNAME
4698 {"CS_HOSTNAME", _CS_HOSTNAME},
4699#endif
4700#ifdef _CS_HW_PROVIDER
4701 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4702#endif
4703#ifdef _CS_HW_SERIAL
4704 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4705#endif
4706#ifdef _CS_INITTAB_NAME
4707 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4708#endif
Fred Drakec9680921999-12-13 16:37:25 +00004709#ifdef _CS_LFS64_CFLAGS
4710 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4711#endif
4712#ifdef _CS_LFS64_LDFLAGS
4713 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4714#endif
4715#ifdef _CS_LFS64_LIBS
4716 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4717#endif
4718#ifdef _CS_LFS64_LINTFLAGS
4719 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4720#endif
4721#ifdef _CS_LFS_CFLAGS
4722 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4723#endif
4724#ifdef _CS_LFS_LDFLAGS
4725 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4726#endif
4727#ifdef _CS_LFS_LIBS
4728 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4729#endif
4730#ifdef _CS_LFS_LINTFLAGS
4731 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4732#endif
Fred Draked86ed291999-12-15 15:34:33 +00004733#ifdef _CS_MACHINE
4734 {"CS_MACHINE", _CS_MACHINE},
4735#endif
Fred Drakec9680921999-12-13 16:37:25 +00004736#ifdef _CS_PATH
4737 {"CS_PATH", _CS_PATH},
4738#endif
Fred Draked86ed291999-12-15 15:34:33 +00004739#ifdef _CS_RELEASE
4740 {"CS_RELEASE", _CS_RELEASE},
4741#endif
4742#ifdef _CS_SRPC_DOMAIN
4743 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4744#endif
4745#ifdef _CS_SYSNAME
4746 {"CS_SYSNAME", _CS_SYSNAME},
4747#endif
4748#ifdef _CS_VERSION
4749 {"CS_VERSION", _CS_VERSION},
4750#endif
Fred Drakec9680921999-12-13 16:37:25 +00004751#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4752 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4753#endif
4754#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4755 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4756#endif
4757#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4758 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4759#endif
4760#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4761 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4762#endif
4763#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4764 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4765#endif
4766#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4767 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4768#endif
4769#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4770 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4771#endif
4772#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4773 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4774#endif
4775#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4776 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4777#endif
4778#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4779 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4780#endif
4781#ifdef _CS_XBS5_LP64_OFF64_LIBS
4782 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4783#endif
4784#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4785 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4786#endif
4787#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4788 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4789#endif
4790#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4791 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4792#endif
4793#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4794 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4795#endif
4796#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4797 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4798#endif
Fred Draked86ed291999-12-15 15:34:33 +00004799#ifdef _MIPS_CS_AVAIL_PROCESSORS
4800 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4801#endif
4802#ifdef _MIPS_CS_BASE
4803 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4804#endif
4805#ifdef _MIPS_CS_HOSTID
4806 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4807#endif
4808#ifdef _MIPS_CS_HW_NAME
4809 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4810#endif
4811#ifdef _MIPS_CS_NUM_PROCESSORS
4812 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4813#endif
4814#ifdef _MIPS_CS_OSREL_MAJ
4815 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4816#endif
4817#ifdef _MIPS_CS_OSREL_MIN
4818 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4819#endif
4820#ifdef _MIPS_CS_OSREL_PATCH
4821 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4822#endif
4823#ifdef _MIPS_CS_OS_NAME
4824 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4825#endif
4826#ifdef _MIPS_CS_OS_PROVIDER
4827 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4828#endif
4829#ifdef _MIPS_CS_PROCESSORS
4830 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4831#endif
4832#ifdef _MIPS_CS_SERIAL
4833 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4834#endif
4835#ifdef _MIPS_CS_VENDOR
4836 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4837#endif
Fred Drakec9680921999-12-13 16:37:25 +00004838};
4839
4840static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004841conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004842{
4843 return conv_confname(arg, valuep, posix_constants_confstr,
4844 sizeof(posix_constants_confstr)
4845 / sizeof(struct constdef));
4846}
4847
4848static char posix_confstr__doc__[] = "\
4849confstr(name) -> string\n\
4850Return a string-valued system configuration variable.";
4851
4852static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004853posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004854{
4855 PyObject *result = NULL;
4856 int name;
4857 char buffer[64];
4858
4859 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4860 int len = confstr(name, buffer, sizeof(buffer));
4861
Fred Drakec9680921999-12-13 16:37:25 +00004862 errno = 0;
4863 if (len == 0) {
4864 if (errno != 0)
4865 posix_error();
4866 else
4867 result = PyString_FromString("");
4868 }
4869 else {
4870 if (len >= sizeof(buffer)) {
4871 result = PyString_FromStringAndSize(NULL, len);
4872 if (result != NULL)
4873 confstr(name, PyString_AS_STRING(result), len+1);
4874 }
4875 else
4876 result = PyString_FromString(buffer);
4877 }
4878 }
4879 return result;
4880}
4881#endif
4882
4883
4884#ifdef HAVE_SYSCONF
4885static struct constdef posix_constants_sysconf[] = {
4886#ifdef _SC_2_CHAR_TERM
4887 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4888#endif
4889#ifdef _SC_2_C_BIND
4890 {"SC_2_C_BIND", _SC_2_C_BIND},
4891#endif
4892#ifdef _SC_2_C_DEV
4893 {"SC_2_C_DEV", _SC_2_C_DEV},
4894#endif
4895#ifdef _SC_2_C_VERSION
4896 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4897#endif
4898#ifdef _SC_2_FORT_DEV
4899 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4900#endif
4901#ifdef _SC_2_FORT_RUN
4902 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4903#endif
4904#ifdef _SC_2_LOCALEDEF
4905 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4906#endif
4907#ifdef _SC_2_SW_DEV
4908 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4909#endif
4910#ifdef _SC_2_UPE
4911 {"SC_2_UPE", _SC_2_UPE},
4912#endif
4913#ifdef _SC_2_VERSION
4914 {"SC_2_VERSION", _SC_2_VERSION},
4915#endif
Fred Draked86ed291999-12-15 15:34:33 +00004916#ifdef _SC_ABI_ASYNCHRONOUS_IO
4917 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4918#endif
4919#ifdef _SC_ACL
4920 {"SC_ACL", _SC_ACL},
4921#endif
Fred Drakec9680921999-12-13 16:37:25 +00004922#ifdef _SC_AIO_LISTIO_MAX
4923 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4924#endif
Fred Drakec9680921999-12-13 16:37:25 +00004925#ifdef _SC_AIO_MAX
4926 {"SC_AIO_MAX", _SC_AIO_MAX},
4927#endif
4928#ifdef _SC_AIO_PRIO_DELTA_MAX
4929 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4930#endif
4931#ifdef _SC_ARG_MAX
4932 {"SC_ARG_MAX", _SC_ARG_MAX},
4933#endif
4934#ifdef _SC_ASYNCHRONOUS_IO
4935 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4936#endif
4937#ifdef _SC_ATEXIT_MAX
4938 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4939#endif
Fred Draked86ed291999-12-15 15:34:33 +00004940#ifdef _SC_AUDIT
4941 {"SC_AUDIT", _SC_AUDIT},
4942#endif
Fred Drakec9680921999-12-13 16:37:25 +00004943#ifdef _SC_AVPHYS_PAGES
4944 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4945#endif
4946#ifdef _SC_BC_BASE_MAX
4947 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4948#endif
4949#ifdef _SC_BC_DIM_MAX
4950 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4951#endif
4952#ifdef _SC_BC_SCALE_MAX
4953 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4954#endif
4955#ifdef _SC_BC_STRING_MAX
4956 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4957#endif
Fred Draked86ed291999-12-15 15:34:33 +00004958#ifdef _SC_CAP
4959 {"SC_CAP", _SC_CAP},
4960#endif
Fred Drakec9680921999-12-13 16:37:25 +00004961#ifdef _SC_CHARCLASS_NAME_MAX
4962 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4963#endif
4964#ifdef _SC_CHAR_BIT
4965 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4966#endif
4967#ifdef _SC_CHAR_MAX
4968 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4969#endif
4970#ifdef _SC_CHAR_MIN
4971 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4972#endif
4973#ifdef _SC_CHILD_MAX
4974 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4975#endif
4976#ifdef _SC_CLK_TCK
4977 {"SC_CLK_TCK", _SC_CLK_TCK},
4978#endif
4979#ifdef _SC_COHER_BLKSZ
4980 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4981#endif
4982#ifdef _SC_COLL_WEIGHTS_MAX
4983 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4984#endif
4985#ifdef _SC_DCACHE_ASSOC
4986 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4987#endif
4988#ifdef _SC_DCACHE_BLKSZ
4989 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4990#endif
4991#ifdef _SC_DCACHE_LINESZ
4992 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4993#endif
4994#ifdef _SC_DCACHE_SZ
4995 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4996#endif
4997#ifdef _SC_DCACHE_TBLKSZ
4998 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4999#endif
5000#ifdef _SC_DELAYTIMER_MAX
5001 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5002#endif
5003#ifdef _SC_EQUIV_CLASS_MAX
5004 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5005#endif
5006#ifdef _SC_EXPR_NEST_MAX
5007 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5008#endif
5009#ifdef _SC_FSYNC
5010 {"SC_FSYNC", _SC_FSYNC},
5011#endif
5012#ifdef _SC_GETGR_R_SIZE_MAX
5013 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5014#endif
5015#ifdef _SC_GETPW_R_SIZE_MAX
5016 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5017#endif
5018#ifdef _SC_ICACHE_ASSOC
5019 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5020#endif
5021#ifdef _SC_ICACHE_BLKSZ
5022 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5023#endif
5024#ifdef _SC_ICACHE_LINESZ
5025 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5026#endif
5027#ifdef _SC_ICACHE_SZ
5028 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5029#endif
Fred Draked86ed291999-12-15 15:34:33 +00005030#ifdef _SC_INF
5031 {"SC_INF", _SC_INF},
5032#endif
Fred Drakec9680921999-12-13 16:37:25 +00005033#ifdef _SC_INT_MAX
5034 {"SC_INT_MAX", _SC_INT_MAX},
5035#endif
5036#ifdef _SC_INT_MIN
5037 {"SC_INT_MIN", _SC_INT_MIN},
5038#endif
5039#ifdef _SC_IOV_MAX
5040 {"SC_IOV_MAX", _SC_IOV_MAX},
5041#endif
Fred Draked86ed291999-12-15 15:34:33 +00005042#ifdef _SC_IP_SECOPTS
5043 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5044#endif
Fred Drakec9680921999-12-13 16:37:25 +00005045#ifdef _SC_JOB_CONTROL
5046 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5047#endif
Fred Draked86ed291999-12-15 15:34:33 +00005048#ifdef _SC_KERN_POINTERS
5049 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5050#endif
5051#ifdef _SC_KERN_SIM
5052 {"SC_KERN_SIM", _SC_KERN_SIM},
5053#endif
Fred Drakec9680921999-12-13 16:37:25 +00005054#ifdef _SC_LINE_MAX
5055 {"SC_LINE_MAX", _SC_LINE_MAX},
5056#endif
5057#ifdef _SC_LOGIN_NAME_MAX
5058 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5059#endif
5060#ifdef _SC_LOGNAME_MAX
5061 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5062#endif
5063#ifdef _SC_LONG_BIT
5064 {"SC_LONG_BIT", _SC_LONG_BIT},
5065#endif
Fred Draked86ed291999-12-15 15:34:33 +00005066#ifdef _SC_MAC
5067 {"SC_MAC", _SC_MAC},
5068#endif
Fred Drakec9680921999-12-13 16:37:25 +00005069#ifdef _SC_MAPPED_FILES
5070 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5071#endif
5072#ifdef _SC_MAXPID
5073 {"SC_MAXPID", _SC_MAXPID},
5074#endif
5075#ifdef _SC_MB_LEN_MAX
5076 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5077#endif
5078#ifdef _SC_MEMLOCK
5079 {"SC_MEMLOCK", _SC_MEMLOCK},
5080#endif
5081#ifdef _SC_MEMLOCK_RANGE
5082 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5083#endif
5084#ifdef _SC_MEMORY_PROTECTION
5085 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5086#endif
5087#ifdef _SC_MESSAGE_PASSING
5088 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5089#endif
Fred Draked86ed291999-12-15 15:34:33 +00005090#ifdef _SC_MMAP_FIXED_ALIGNMENT
5091 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5092#endif
Fred Drakec9680921999-12-13 16:37:25 +00005093#ifdef _SC_MQ_OPEN_MAX
5094 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5095#endif
5096#ifdef _SC_MQ_PRIO_MAX
5097 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5098#endif
Fred Draked86ed291999-12-15 15:34:33 +00005099#ifdef _SC_NACLS_MAX
5100 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5101#endif
Fred Drakec9680921999-12-13 16:37:25 +00005102#ifdef _SC_NGROUPS_MAX
5103 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5104#endif
5105#ifdef _SC_NL_ARGMAX
5106 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5107#endif
5108#ifdef _SC_NL_LANGMAX
5109 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5110#endif
5111#ifdef _SC_NL_MSGMAX
5112 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5113#endif
5114#ifdef _SC_NL_NMAX
5115 {"SC_NL_NMAX", _SC_NL_NMAX},
5116#endif
5117#ifdef _SC_NL_SETMAX
5118 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5119#endif
5120#ifdef _SC_NL_TEXTMAX
5121 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5122#endif
5123#ifdef _SC_NPROCESSORS_CONF
5124 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5125#endif
5126#ifdef _SC_NPROCESSORS_ONLN
5127 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5128#endif
Fred Draked86ed291999-12-15 15:34:33 +00005129#ifdef _SC_NPROC_CONF
5130 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5131#endif
5132#ifdef _SC_NPROC_ONLN
5133 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5134#endif
Fred Drakec9680921999-12-13 16:37:25 +00005135#ifdef _SC_NZERO
5136 {"SC_NZERO", _SC_NZERO},
5137#endif
5138#ifdef _SC_OPEN_MAX
5139 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5140#endif
5141#ifdef _SC_PAGESIZE
5142 {"SC_PAGESIZE", _SC_PAGESIZE},
5143#endif
5144#ifdef _SC_PAGE_SIZE
5145 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5146#endif
5147#ifdef _SC_PASS_MAX
5148 {"SC_PASS_MAX", _SC_PASS_MAX},
5149#endif
5150#ifdef _SC_PHYS_PAGES
5151 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5152#endif
5153#ifdef _SC_PII
5154 {"SC_PII", _SC_PII},
5155#endif
5156#ifdef _SC_PII_INTERNET
5157 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5158#endif
5159#ifdef _SC_PII_INTERNET_DGRAM
5160 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5161#endif
5162#ifdef _SC_PII_INTERNET_STREAM
5163 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5164#endif
5165#ifdef _SC_PII_OSI
5166 {"SC_PII_OSI", _SC_PII_OSI},
5167#endif
5168#ifdef _SC_PII_OSI_CLTS
5169 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5170#endif
5171#ifdef _SC_PII_OSI_COTS
5172 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5173#endif
5174#ifdef _SC_PII_OSI_M
5175 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5176#endif
5177#ifdef _SC_PII_SOCKET
5178 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5179#endif
5180#ifdef _SC_PII_XTI
5181 {"SC_PII_XTI", _SC_PII_XTI},
5182#endif
5183#ifdef _SC_POLL
5184 {"SC_POLL", _SC_POLL},
5185#endif
5186#ifdef _SC_PRIORITIZED_IO
5187 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5188#endif
5189#ifdef _SC_PRIORITY_SCHEDULING
5190 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5191#endif
5192#ifdef _SC_REALTIME_SIGNALS
5193 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5194#endif
5195#ifdef _SC_RE_DUP_MAX
5196 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5197#endif
5198#ifdef _SC_RTSIG_MAX
5199 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5200#endif
5201#ifdef _SC_SAVED_IDS
5202 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5203#endif
5204#ifdef _SC_SCHAR_MAX
5205 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5206#endif
5207#ifdef _SC_SCHAR_MIN
5208 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5209#endif
5210#ifdef _SC_SELECT
5211 {"SC_SELECT", _SC_SELECT},
5212#endif
5213#ifdef _SC_SEMAPHORES
5214 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5215#endif
5216#ifdef _SC_SEM_NSEMS_MAX
5217 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5218#endif
5219#ifdef _SC_SEM_VALUE_MAX
5220 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5221#endif
5222#ifdef _SC_SHARED_MEMORY_OBJECTS
5223 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5224#endif
5225#ifdef _SC_SHRT_MAX
5226 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5227#endif
5228#ifdef _SC_SHRT_MIN
5229 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5230#endif
5231#ifdef _SC_SIGQUEUE_MAX
5232 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5233#endif
5234#ifdef _SC_SIGRT_MAX
5235 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5236#endif
5237#ifdef _SC_SIGRT_MIN
5238 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5239#endif
Fred Draked86ed291999-12-15 15:34:33 +00005240#ifdef _SC_SOFTPOWER
5241 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5242#endif
Fred Drakec9680921999-12-13 16:37:25 +00005243#ifdef _SC_SPLIT_CACHE
5244 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5245#endif
5246#ifdef _SC_SSIZE_MAX
5247 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5248#endif
5249#ifdef _SC_STACK_PROT
5250 {"SC_STACK_PROT", _SC_STACK_PROT},
5251#endif
5252#ifdef _SC_STREAM_MAX
5253 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5254#endif
5255#ifdef _SC_SYNCHRONIZED_IO
5256 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5257#endif
5258#ifdef _SC_THREADS
5259 {"SC_THREADS", _SC_THREADS},
5260#endif
5261#ifdef _SC_THREAD_ATTR_STACKADDR
5262 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5263#endif
5264#ifdef _SC_THREAD_ATTR_STACKSIZE
5265 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5266#endif
5267#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5268 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5269#endif
5270#ifdef _SC_THREAD_KEYS_MAX
5271 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5272#endif
5273#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5274 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5275#endif
5276#ifdef _SC_THREAD_PRIO_INHERIT
5277 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5278#endif
5279#ifdef _SC_THREAD_PRIO_PROTECT
5280 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5281#endif
5282#ifdef _SC_THREAD_PROCESS_SHARED
5283 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5284#endif
5285#ifdef _SC_THREAD_SAFE_FUNCTIONS
5286 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5287#endif
5288#ifdef _SC_THREAD_STACK_MIN
5289 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5290#endif
5291#ifdef _SC_THREAD_THREADS_MAX
5292 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5293#endif
5294#ifdef _SC_TIMERS
5295 {"SC_TIMERS", _SC_TIMERS},
5296#endif
5297#ifdef _SC_TIMER_MAX
5298 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5299#endif
5300#ifdef _SC_TTY_NAME_MAX
5301 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5302#endif
5303#ifdef _SC_TZNAME_MAX
5304 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5305#endif
5306#ifdef _SC_T_IOV_MAX
5307 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5308#endif
5309#ifdef _SC_UCHAR_MAX
5310 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5311#endif
5312#ifdef _SC_UINT_MAX
5313 {"SC_UINT_MAX", _SC_UINT_MAX},
5314#endif
5315#ifdef _SC_UIO_MAXIOV
5316 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5317#endif
5318#ifdef _SC_ULONG_MAX
5319 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5320#endif
5321#ifdef _SC_USHRT_MAX
5322 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5323#endif
5324#ifdef _SC_VERSION
5325 {"SC_VERSION", _SC_VERSION},
5326#endif
5327#ifdef _SC_WORD_BIT
5328 {"SC_WORD_BIT", _SC_WORD_BIT},
5329#endif
5330#ifdef _SC_XBS5_ILP32_OFF32
5331 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5332#endif
5333#ifdef _SC_XBS5_ILP32_OFFBIG
5334 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5335#endif
5336#ifdef _SC_XBS5_LP64_OFF64
5337 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5338#endif
5339#ifdef _SC_XBS5_LPBIG_OFFBIG
5340 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5341#endif
5342#ifdef _SC_XOPEN_CRYPT
5343 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5344#endif
5345#ifdef _SC_XOPEN_ENH_I18N
5346 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5347#endif
5348#ifdef _SC_XOPEN_LEGACY
5349 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5350#endif
5351#ifdef _SC_XOPEN_REALTIME
5352 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5353#endif
5354#ifdef _SC_XOPEN_REALTIME_THREADS
5355 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5356#endif
5357#ifdef _SC_XOPEN_SHM
5358 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5359#endif
5360#ifdef _SC_XOPEN_UNIX
5361 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5362#endif
5363#ifdef _SC_XOPEN_VERSION
5364 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5365#endif
5366#ifdef _SC_XOPEN_XCU_VERSION
5367 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5368#endif
5369#ifdef _SC_XOPEN_XPG2
5370 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5371#endif
5372#ifdef _SC_XOPEN_XPG3
5373 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5374#endif
5375#ifdef _SC_XOPEN_XPG4
5376 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5377#endif
5378};
5379
5380static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005381conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005382{
5383 return conv_confname(arg, valuep, posix_constants_sysconf,
5384 sizeof(posix_constants_sysconf)
5385 / sizeof(struct constdef));
5386}
5387
5388static char posix_sysconf__doc__[] = "\
5389sysconf(name) -> integer\n\
5390Return an integer-valued system configuration variable.";
5391
5392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005393posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005394{
5395 PyObject *result = NULL;
5396 int name;
5397
5398 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5399 int value;
5400
5401 errno = 0;
5402 value = sysconf(name);
5403 if (value == -1 && errno != 0)
5404 posix_error();
5405 else
5406 result = PyInt_FromLong(value);
5407 }
5408 return result;
5409}
5410#endif
5411
5412
Fred Drakebec628d1999-12-15 18:31:10 +00005413/* This code is used to ensure that the tables of configuration value names
5414 * are in sorted order as required by conv_confname(), and also to build the
5415 * the exported dictionaries that are used to publish information about the
5416 * names available on the host platform.
5417 *
5418 * Sorting the table at runtime ensures that the table is properly ordered
5419 * when used, even for platforms we're not able to test on. It also makes
5420 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005421 */
Fred Drakebec628d1999-12-15 18:31:10 +00005422
5423static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005424cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005425{
5426 const struct constdef *c1 =
5427 (const struct constdef *) v1;
5428 const struct constdef *c2 =
5429 (const struct constdef *) v2;
5430
5431 return strcmp(c1->name, c2->name);
5432}
5433
5434static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005435setup_confname_table(struct constdef *table, size_t tablesize,
5436 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005437{
Fred Drakebec628d1999-12-15 18:31:10 +00005438 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005439 size_t i;
5440 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005441
5442 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5443 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005444 if (d == NULL)
5445 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005446
Barry Warsaw3155db32000-04-13 15:20:40 +00005447 for (i=0; i < tablesize; ++i) {
5448 PyObject *o = PyInt_FromLong(table[i].value);
5449 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5450 Py_XDECREF(o);
5451 Py_DECREF(d);
5452 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005453 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005454 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005455 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005456 status = PyDict_SetItemString(moddict, tablename, d);
5457 Py_DECREF(d);
5458 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005459}
5460
Fred Drakebec628d1999-12-15 18:31:10 +00005461/* Return -1 on failure, 0 on success. */
5462static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005463setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005464{
5465#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005466 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005467 sizeof(posix_constants_pathconf)
5468 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005469 "pathconf_names", moddict))
5470 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005471#endif
5472#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005473 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005474 sizeof(posix_constants_confstr)
5475 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005476 "confstr_names", moddict))
5477 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005478#endif
5479#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005480 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005481 sizeof(posix_constants_sysconf)
5482 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005483 "sysconf_names", moddict))
5484 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005485#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005486 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005487}
Fred Draked86ed291999-12-15 15:34:33 +00005488
5489
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005490static char posix_abort__doc__[] = "\
5491abort() -> does not return!\n\
5492Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5493in the hardest way possible on the hosting operating system.";
5494
5495static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005496posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005497{
5498 if (!PyArg_ParseTuple(args, ":abort"))
5499 return NULL;
5500 abort();
5501 /*NOTREACHED*/
5502 Py_FatalError("abort() called from Python code didn't abort!");
5503 return NULL;
5504}
Fred Drakebec628d1999-12-15 18:31:10 +00005505
Tim Petersf58a7aa2000-09-22 10:05:54 +00005506#ifdef MS_WIN32
5507static char win32_startfile__doc__[] = "\
5508startfile(filepath) - Start a file with its associated application.\n\
5509\n\
5510This acts like double-clicking the file in Explorer, or giving the file\n\
5511name as an argument to the DOS \"start\" command: the file is opened\n\
5512with whatever application (if any) its extension is associated.\n\
5513\n\
5514startfile returns as soon as the associated application is launched.\n\
5515There is no option to wait for the application to close, and no way\n\
5516to retrieve the application's exit status.\n\
5517\n\
5518The filepath is relative to the current directory. If you want to use\n\
5519an absolute path, make sure the first character is not a slash (\"/\");\n\
5520the underlying Win32 ShellExecute function doesn't work if it is.";
5521
5522static PyObject *
5523win32_startfile(PyObject *self, PyObject *args)
5524{
5525 char *filepath;
5526 HINSTANCE rc;
5527 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5528 return NULL;
5529 Py_BEGIN_ALLOW_THREADS
5530 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5531 Py_END_ALLOW_THREADS
5532 if (rc <= (HINSTANCE)32)
5533 return win32_error("startfile", filepath);
5534 Py_INCREF(Py_None);
5535 return Py_None;
5536}
5537#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005538
5539static PyMethodDef posix_methods[] = {
5540 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5541#ifdef HAVE_TTYNAME
5542 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5543#endif
5544 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5545 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005546#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005547 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005548#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005549#ifdef HAVE_CHROOT
5550 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5551#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005552#ifdef HAVE_CTERMID
5553 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5554#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005555#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005556 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005557#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005558#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005559 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005560#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005561 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5562 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5563 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005564#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005565 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005566#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005567#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005568 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005569#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005570 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5571 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5572 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005573#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005574 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005575#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005576#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005577 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005578#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005579 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005580#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005581 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005582#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005583 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5584 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5585 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005586#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005587 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005588#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005589 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005590#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005591 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5592 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005593#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005594#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005595 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5596 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005597#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005598#ifdef HAVE_FORK1
5599 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5600#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005601#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005602 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005603#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005604#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005605 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005606#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005607#ifdef HAVE_FORKPTY
5608 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5609#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005610#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005611 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005612#endif /* HAVE_GETEGID */
5613#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005614 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005615#endif /* HAVE_GETEUID */
5616#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005617 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005618#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005619#ifdef HAVE_GETGROUPS
5620 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5621#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005622 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005623#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005624 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005625#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005626#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005627 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005628#endif /* HAVE_GETPPID */
5629#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005630 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005631#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005632#ifdef HAVE_GETLOGIN
5633 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5634#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005635#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005636 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005637#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005638#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005639 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005640#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005641#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005642 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005643#ifdef MS_WIN32
5644 {"popen2", win32_popen2, METH_VARARGS},
5645 {"popen3", win32_popen3, METH_VARARGS},
5646 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005647 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005648#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005649#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005650#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005651 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005652#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005653#ifdef HAVE_SETEUID
5654 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5655#endif /* HAVE_SETEUID */
5656#ifdef HAVE_SETEGID
5657 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5658#endif /* HAVE_SETEGID */
5659#ifdef HAVE_SETREUID
5660 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5661#endif /* HAVE_SETREUID */
5662#ifdef HAVE_SETREGID
5663 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5664#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005665#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005666 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005667#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005668#ifdef HAVE_SETGROUPS
5669 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5670#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005671#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005672 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005673#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005674#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005675 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005676#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005677#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005678 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005679#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005680#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005681 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005682#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005683#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005684 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005685#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005686#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005687 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005688#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005689#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005690 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005691#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005692 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5693 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5694 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5695 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5696 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5697 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5698 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5699 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5700 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005701 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005702#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005703 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005704#endif
5705#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005706 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005707#endif
5708#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005709 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005710#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005711#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005712 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005713#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005714#ifdef HAVE_UNSETENV
5715 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
5716#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005717#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005718 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005719#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005720#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005721 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005722#endif
5723#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005724 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005725#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005726#ifdef HAVE_SYS_WAIT_H
5727#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005728 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005729#endif /* WIFSTOPPED */
5730#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005731 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005732#endif /* WIFSIGNALED */
5733#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005734 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005735#endif /* WIFEXITED */
5736#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005737 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005738#endif /* WEXITSTATUS */
5739#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005740 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005741#endif /* WTERMSIG */
5742#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005743 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005744#endif /* WSTOPSIG */
5745#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005746#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005747 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005748#endif
5749#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005750 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005751#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005752#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005753 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5754#endif
5755#ifdef HAVE_TEMPNAM
5756 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5757#endif
5758#ifdef HAVE_TMPNAM
5759 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5760#endif
Fred Drakec9680921999-12-13 16:37:25 +00005761#ifdef HAVE_CONFSTR
5762 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5763#endif
5764#ifdef HAVE_SYSCONF
5765 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5766#endif
5767#ifdef HAVE_FPATHCONF
5768 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5769#endif
5770#ifdef HAVE_PATHCONF
5771 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5772#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005773 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005774#ifdef MS_WIN32
5775 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5776#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005777 {NULL, NULL} /* Sentinel */
5778};
5779
5780
Barry Warsaw4a342091996-12-19 23:50:02 +00005781static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005782ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005783{
5784 PyObject* v = PyInt_FromLong(value);
5785 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5786 return -1; /* triggers fatal error */
5787
5788 Py_DECREF(v);
5789 return 0;
5790}
5791
Guido van Rossumd48f2521997-12-05 22:19:34 +00005792#if defined(PYOS_OS2)
5793/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5794static int insertvalues(PyObject *d)
5795{
5796 APIRET rc;
5797 ULONG values[QSV_MAX+1];
5798 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00005799 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00005800
5801 Py_BEGIN_ALLOW_THREADS
5802 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5803 Py_END_ALLOW_THREADS
5804
5805 if (rc != NO_ERROR) {
5806 os2_error(rc);
5807 return -1;
5808 }
5809
5810 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5811 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5812 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5813 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5814 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5815 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5816 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5817
5818 switch (values[QSV_VERSION_MINOR]) {
5819 case 0: ver = "2.00"; break;
5820 case 10: ver = "2.10"; break;
5821 case 11: ver = "2.11"; break;
5822 case 30: ver = "3.00"; break;
5823 case 40: ver = "4.00"; break;
5824 case 50: ver = "5.00"; break;
5825 default:
Tim Peters885d4572001-11-28 20:27:42 +00005826 PyOS_snprintf(tmp, sizeof(tmp),
5827 "%d-%d", values[QSV_VERSION_MAJOR],
5828 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005829 ver = &tmp[0];
5830 }
5831
5832 /* Add Indicator of the Version of the Operating System */
5833 v = PyString_FromString(ver);
5834 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5835 return -1;
5836 Py_DECREF(v);
5837
5838 /* Add Indicator of Which Drive was Used to Boot the System */
5839 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5840 tmp[1] = ':';
5841 tmp[2] = '\0';
5842
5843 v = PyString_FromString(tmp);
5844 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5845 return -1;
5846 Py_DECREF(v);
5847
5848 return 0;
5849}
5850#endif
5851
Barry Warsaw4a342091996-12-19 23:50:02 +00005852static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005853all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005854{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005855#ifdef F_OK
5856 if (ins(d, "F_OK", (long)F_OK)) return -1;
5857#endif
5858#ifdef R_OK
5859 if (ins(d, "R_OK", (long)R_OK)) return -1;
5860#endif
5861#ifdef W_OK
5862 if (ins(d, "W_OK", (long)W_OK)) return -1;
5863#endif
5864#ifdef X_OK
5865 if (ins(d, "X_OK", (long)X_OK)) return -1;
5866#endif
Fred Drakec9680921999-12-13 16:37:25 +00005867#ifdef NGROUPS_MAX
5868 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5869#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005870#ifdef TMP_MAX
5871 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5872#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005873#ifdef WNOHANG
5874 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5875#endif
5876#ifdef O_RDONLY
5877 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5878#endif
5879#ifdef O_WRONLY
5880 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5881#endif
5882#ifdef O_RDWR
5883 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5884#endif
5885#ifdef O_NDELAY
5886 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5887#endif
5888#ifdef O_NONBLOCK
5889 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5890#endif
5891#ifdef O_APPEND
5892 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5893#endif
5894#ifdef O_DSYNC
5895 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5896#endif
5897#ifdef O_RSYNC
5898 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5899#endif
5900#ifdef O_SYNC
5901 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5902#endif
5903#ifdef O_NOCTTY
5904 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5905#endif
5906#ifdef O_CREAT
5907 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5908#endif
5909#ifdef O_EXCL
5910 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5911#endif
5912#ifdef O_TRUNC
5913 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5914#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005915#ifdef O_BINARY
5916 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5917#endif
5918#ifdef O_TEXT
5919 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5920#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005921#ifdef O_LARGEFILE
5922 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
5923#endif
5924
5925/* GNU extensions. */
5926#ifdef O_DIRECT
5927 /* Direct disk access. */
5928 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
5929#endif
5930#ifdef O_DIRECTORY
5931 /* Must be a directory. */
5932 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
5933#endif
5934#ifdef O_NOFOLLOW
5935 /* Do not follow links. */
5936 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
5937#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005938
Guido van Rossum246bc171999-02-01 23:54:31 +00005939#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005940 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5941 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5942 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5943 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5944 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005945#endif
5946
Guido van Rossumd48f2521997-12-05 22:19:34 +00005947#if defined(PYOS_OS2)
5948 if (insertvalues(d)) return -1;
5949#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005950 return 0;
5951}
5952
5953
Tim Peters58e0a8c2001-05-14 22:32:33 +00005954#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005955#define INITFUNC initnt
5956#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005957
5958#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005959#define INITFUNC initos2
5960#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005961
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005962#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005963#define INITFUNC initposix
5964#define MODNAME "posix"
5965#endif
5966
Guido van Rossum3886bb61998-12-04 18:50:17 +00005967DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005968INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005969{
Barry Warsaw53699e91996-12-10 23:23:01 +00005970 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005971
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005972 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005973 posix_methods,
5974 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005975 (PyObject *)NULL,
5976 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005977 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005978
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005979 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005980 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005981 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005982 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005983 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005984
Barry Warsaw4a342091996-12-19 23:50:02 +00005985 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005986 return;
5987
Fred Drakebec628d1999-12-15 18:31:10 +00005988 if (setup_confname_tables(d))
5989 return;
5990
Barry Warsawca74da41999-02-09 19:31:45 +00005991 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005992
Guido van Rossumb3d39562000-01-31 18:41:26 +00005993#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005994 if (posix_putenv_garbage == NULL)
5995 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005996#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005997
5998 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
5999 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
6000
6001 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
6002 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006003}