blob: 20765e199b0feb55d280bc639e5b15c416995ebe [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004/* This file is also used for Windows NT and MS-Win. In that case the module
Guido van Rossumad0ee831995-03-01 10:34:45 +00005 actually calls itself 'nt', not 'posix', and a few functions are
6 either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +00007 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000013static char posix__doc__ [] =
14"This module provides access to operating system functionality that is\n\
15standardized by the C Standard and the POSIX standard (a thinly\n\
16disguised Unix interface). Refer to the library manual and\n\
17corresponding Unix manual entries for more information on calls.";
18
Barry Warsaw53699e91996-12-10 23:23:01 +000019#include "Python.h"
Guido van Rossum98bf58f2001-10-18 20:34:25 +000020#include "structseq.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000021
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000022#if defined(PYOS_OS2)
23#define INCL_DOS
24#define INCL_DOSERRORS
25#define INCL_DOSPROCESS
26#define INCL_NOPMAPI
27#include <os2.h>
28#endif
29
Guido van Rossumb6775db1994-08-01 11:34:53 +000030#include <sys/types.h>
31#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000032
Guido van Rossum36bc6801995-06-14 22:54:23 +000033#ifdef HAVE_SYS_WAIT_H
34#include <sys/wait.h> /* For WNOHANG */
35#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000036
Guido van Rossuma376cc51996-12-05 23:43:35 +000037#ifdef HAVE_SIGNAL_H
38#include <signal.h>
39#endif
40
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#ifdef HAVE_FCNTL_H
42#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000043#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000044
Guido van Rossuma6535fd2001-10-18 19:44:10 +000045#ifdef HAVE_GRP_H
46#include <grp.h>
47#endif
48
Skip Montanaro8216c182001-02-27 17:04:34 +000049/* pick up declaration of confstr on some systems? */
50#ifdef HAVE_UNISTD_H
51#include <unistd.h>
52#endif /* HAVE_UNISTD_H */
53
Guido van Rossuma4916fa1996-05-23 22:58:55 +000054/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000055/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000056#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000057#include <process.h>
58#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000059#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000060#define HAVE_GETCWD 1
61#define HAVE_OPENDIR 1
62#define HAVE_SYSTEM 1
63#if defined(__OS2__)
64#define HAVE_EXECV 1
65#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000066#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000067#include <process.h>
68#else
69#ifdef __BORLANDC__ /* Borland compiler */
70#define HAVE_EXECV 1
71#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072#define HAVE_OPENDIR 1
73#define HAVE_PIPE 1
74#define HAVE_POPEN 1
75#define HAVE_SYSTEM 1
76#define HAVE_WAIT 1
77#else
78#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000079#define HAVE_GETCWD 1
80#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000081#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#define HAVE_EXECV 1
83#define HAVE_PIPE 1
84#define HAVE_POPEN 1
85#define HAVE_SYSTEM 1
86#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000087#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#else /* all other compilers */
89/* Unix functions that the configure script doesn't check for */
90#define HAVE_EXECV 1
91#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000092#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
93#define HAVE_FORK1 1
94#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000095#define HAVE_GETCWD 1
96#define HAVE_GETEGID 1
97#define HAVE_GETEUID 1
98#define HAVE_GETGID 1
99#define HAVE_GETPPID 1
100#define HAVE_GETUID 1
101#define HAVE_KILL 1
102#define HAVE_OPENDIR 1
103#define HAVE_PIPE 1
104#define HAVE_POPEN 1
105#define HAVE_SYSTEM 1
106#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000107#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#endif /* _MSC_VER */
109#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000110#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000111#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000112
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000114
Guido van Rossumb6775db1994-08-01 11:34:53 +0000115#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000116#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000117#endif
118
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000119#if defined(sun) && !defined(__SVR4)
120/* SunOS 4.1.4 doesn't have prototypes for these: */
121extern int rename(const char *, const char *);
122extern int pclose(FILE *);
123extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000124extern int fsync(int);
125extern int lstat(const char *, struct stat *);
126extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000127#endif
128
Guido van Rossum36bc6801995-06-14 22:54:23 +0000129#ifdef NeXT
130/* NeXT's <unistd.h> and <utime.h> aren't worth much */
131#undef HAVE_UNISTD_H
132#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000133#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000134/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000135#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000136#endif
137
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000138#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000155#ifdef __BORLANDC__
156extern int chmod(const char *, int);
157#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000159#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int chown(const char *, uid_t, gid_t);
161extern char *getcwd(char *, int);
162extern char *strerror(int);
163extern int link(const char *, const char *);
164extern int rename(const char *, const char *);
165extern int stat(const char *, struct stat *);
166extern int unlink(const char *);
167extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000170#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000173#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000175
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178#ifdef HAVE_UTIME_H
179#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000182#ifdef HAVE_SYS_UTIME_H
183#include <sys/utime.h>
184#define HAVE_UTIME_H /* pretend we do for the rest of this file */
185#endif /* HAVE_SYS_UTIME_H */
186
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187#ifdef HAVE_SYS_TIMES_H
188#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_PARAM_H
192#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifdef HAVE_SYS_UTSNAME_H
196#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
199#ifndef MAXPATHLEN
200#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000201#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000203#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000207#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000208#include <direct.h>
209#define NAMLEN(dirent) strlen((dirent)->d_name)
210#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000214#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000216#endif
217#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000219#endif
220#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000222#endif
223#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <direct.h>
227#include <io.h>
228#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000229#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000231#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000233#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#else /* 16-bit Windows */
235#include <dos.h>
236#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000237#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
Guido van Rossumd48f2521997-12-05 22:19:34 +0000240#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000242#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000244#ifdef UNION_WAIT
245/* Emulate some macros on systems that have a union instead of macros */
246
247#ifndef WIFEXITED
248#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
249#endif
250
251#ifndef WEXITSTATUS
252#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
253#endif
254
255#ifndef WTERMSIG
256#define WTERMSIG(u_wait) ((u_wait).w_termsig)
257#endif
258
259#endif /* UNION_WAIT */
260
Greg Wardb48bc172000-03-01 21:51:56 +0000261/* Don't use the "_r" form if we don't need it (also, won't have a
262 prototype for it, at least on Solaris -- maybe others as well?). */
263#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
264#define USE_CTERMID_R
265#endif
266
267#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
268#define USE_TMPNAM_R
269#endif
270
Fred Drake699f3522000-06-29 21:12:41 +0000271/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000272#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000273#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000274# define STAT _stati64
275# define FSTAT _fstati64
276# define STRUCT_STAT struct _stati64
277#else
278# define STAT stat
279# define FSTAT fstat
280# define STRUCT_STAT struct stat
281#endif
282
283
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284/* Return a dictionary corresponding to the POSIX environment table */
285
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000286#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289
Barry Warsaw53699e91996-12-10 23:23:01 +0000290static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000291convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292{
Barry Warsaw53699e91996-12-10 23:23:01 +0000293 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000295 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296 if (d == NULL)
297 return NULL;
298 if (environ == NULL)
299 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000300 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000302 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000303 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 char *p = strchr(*e, '=');
305 if (p == NULL)
306 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000307 k = PyString_FromStringAndSize(*e, (int)(p-*e));
308 if (k == NULL) {
309 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000311 }
312 v = PyString_FromString(p+1);
313 if (v == NULL) {
314 PyErr_Clear();
315 Py_DECREF(k);
316 continue;
317 }
318 if (PyDict_GetItem(d, k) == NULL) {
319 if (PyDict_SetItem(d, k, v) != 0)
320 PyErr_Clear();
321 }
322 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000323 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000325#if defined(PYOS_OS2)
326 {
327 APIRET rc;
328 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
329
330 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000331 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000332 PyObject *v = PyString_FromString(buffer);
333 PyDict_SetItemString(d, "BEGINLIBPATH", v);
334 Py_DECREF(v);
335 }
336 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
337 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
338 PyObject *v = PyString_FromString(buffer);
339 PyDict_SetItemString(d, "ENDLIBPATH", v);
340 Py_DECREF(v);
341 }
342 }
343#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344 return d;
345}
346
347
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348/* Set a POSIX-specific error from errno, and return NULL */
349
Barry Warsawd58d7641998-07-23 16:14:40 +0000350static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000351posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000352{
Barry Warsawca74da41999-02-09 19:31:45 +0000353 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354}
Barry Warsawd58d7641998-07-23 16:14:40 +0000355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000356posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000357{
Barry Warsawca74da41999-02-09 19:31:45 +0000358 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000359}
360
Mark Hammondef8b6542001-05-13 08:04:26 +0000361static PyObject *
362posix_error_with_allocated_filename(char* name)
363{
364 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
365 PyMem_Free(name);
366 return rc;
367}
368
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000369#ifdef MS_WIN32
370static PyObject *
371win32_error(char* function, char* filename)
372{
Mark Hammond33a6da92000-08-15 00:46:38 +0000373 /* XXX We should pass the function name along in the future.
374 (_winreg.c also wants to pass the function name.)
375 This would however require an additional param to the
376 Windows error object, which is non-trivial.
377 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000378 errno = GetLastError();
379 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000380 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000381 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000382 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000383}
384#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385
Guido van Rossumd48f2521997-12-05 22:19:34 +0000386#if defined(PYOS_OS2)
387/**********************************************************************
388 * Helper Function to Trim and Format OS/2 Messages
389 **********************************************************************/
390 static void
391os2_formatmsg(char *msgbuf, int msglen, char *reason)
392{
393 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
394
395 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
396 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
397
398 while (lastc > msgbuf && isspace(*lastc))
399 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
400 }
401
402 /* Add Optional Reason Text */
403 if (reason) {
404 strcat(msgbuf, " : ");
405 strcat(msgbuf, reason);
406 }
407}
408
409/**********************************************************************
410 * Decode an OS/2 Operating System Error Code
411 *
412 * A convenience function to lookup an OS/2 error code and return a
413 * text message we can use to raise a Python exception.
414 *
415 * Notes:
416 * The messages for errors returned from the OS/2 kernel reside in
417 * the file OSO001.MSG in the \OS2 directory hierarchy.
418 *
419 **********************************************************************/
420 static char *
421os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
422{
423 APIRET rc;
424 ULONG msglen;
425
426 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
427 Py_BEGIN_ALLOW_THREADS
428 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
429 errorcode, "oso001.msg", &msglen);
430 Py_END_ALLOW_THREADS
431
432 if (rc == NO_ERROR)
433 os2_formatmsg(msgbuf, msglen, reason);
434 else
435 sprintf(msgbuf, "unknown OS error #%d", errorcode);
436
437 return msgbuf;
438}
439
440/* Set an OS/2-specific error and return NULL. OS/2 kernel
441 errors are not in a global variable e.g. 'errno' nor are
442 they congruent with posix error numbers. */
443
444static PyObject * os2_error(int code)
445{
446 char text[1024];
447 PyObject *v;
448
449 os2_strerror(text, sizeof(text), code, "");
450
451 v = Py_BuildValue("(is)", code, text);
452 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000453 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000454 Py_DECREF(v);
455 }
456 return NULL; /* Signal to Python that an Exception is Pending */
457}
458
459#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000460
461/* POSIX generic methods */
462
Barry Warsaw53699e91996-12-10 23:23:01 +0000463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000464posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000465{
466 int fd;
467 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000468 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000469 return NULL;
470 Py_BEGIN_ALLOW_THREADS
471 res = (*func)(fd);
472 Py_END_ALLOW_THREADS
473 if (res < 0)
474 return posix_error();
475 Py_INCREF(Py_None);
476 return Py_None;
477}
478
479
480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000481posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000482{
Mark Hammondef8b6542001-05-13 08:04:26 +0000483 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000484 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000485 if (!PyArg_ParseTuple(args, format,
486 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000487 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000488 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000489 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000490 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000491 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000492 return posix_error_with_allocated_filename(path1);
493 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000494 Py_INCREF(Py_None);
495 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000496}
497
Barry Warsaw53699e91996-12-10 23:23:01 +0000498static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000499posix_2str(PyObject *args, char *format,
500 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000501{
Mark Hammondef8b6542001-05-13 08:04:26 +0000502 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000503 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000504 if (!PyArg_ParseTuple(args, format,
505 Py_FileSystemDefaultEncoding, &path1,
506 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000507 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000508 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000509 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000510 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000511 PyMem_Free(path1);
512 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000513 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000514 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000515 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000516 Py_INCREF(Py_None);
517 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000518}
519
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000520static char stat_result__doc__[] =
521"stat_result: Result from stat or lstat.\n\n\
522This object may be accessed either as a tuple of\n\
523 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
524or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
525\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000526Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000527they are available as attributes only.\n\
528\n\
529See os.stat for more information.\n";
530
531static PyStructSequence_Field stat_result_fields[] = {
532 {"st_mode", "protection bits"},
533 {"st_ino", "inode"},
534 {"st_dev", "device"},
535 {"st_nlink", "number of hard links"},
536 {"st_uid", "user ID of owner"},
537 {"st_gid", "group ID of owner"},
538 {"st_size", "total size, in bytes"},
539 {"st_atime", "time of last access"},
540 {"st_mtime", "time of last modification"},
541 {"st_ctime", "time of last change"},
542#ifdef HAVE_ST_BLKSIZE
543 {"st_blksize", "blocksize for filesystem I/O"},
544#endif
545#ifdef HAVE_ST_BLOCKS
546 {"st_blocks", "number of blocks allocated"},
547#endif
548#ifdef HAVE_ST_RDEV
549 {"st_rdev", "device type (if inode device)"},
550#endif
551 {0}
552};
553
554#ifdef HAVE_ST_BLKSIZE
555#define ST_BLKSIZE_IDX 10
556#else
557#define ST_BLKSIZE_IDX 9
558#endif
559
560#ifdef HAVE_ST_BLOCKS
561#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
562#else
563#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
564#endif
565
566#ifdef HAVE_ST_RDEV
567#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
568#else
569#define ST_RDEV_IDX ST_BLOCKS_IDX
570#endif
571
572static PyStructSequence_Desc stat_result_desc = {
573 "stat_result", /* name */
574 stat_result__doc__, /* doc */
575 stat_result_fields,
576 10
577};
578
579static char statvfs_result__doc__[] =
580"statvfs_result: Result from statvfs or fstatvfs.\n\n\
581This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000582 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
583or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000584\n\
585See os.statvfs for more information.\n";
586
587static PyStructSequence_Field statvfs_result_fields[] = {
588 {"f_bsize", },
589 {"f_frsize", },
590 {"f_blocks", },
591 {"f_bfree", },
592 {"f_bavail", },
593 {"f_files", },
594 {"f_ffree", },
595 {"f_favail", },
596 {"f_flag", },
597 {"f_namemax",},
598 {0}
599};
600
601static PyStructSequence_Desc statvfs_result_desc = {
602 "statvfs_result", /* name */
603 statvfs_result__doc__, /* doc */
604 statvfs_result_fields,
605 10
606};
607
608static PyTypeObject StatResultType;
609static PyTypeObject StatVFSResultType;
610
Fred Drake699f3522000-06-29 21:12:41 +0000611/* pack a system stat C structure into the Python stat tuple
612 (used by posix_stat() and posix_fstat()) */
613static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000614_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000615{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000616 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000617 if (v == NULL)
618 return NULL;
619
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000620 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000621#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000622 PyStructSequence_SET_ITEM(v, 1,
623 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000624#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000625 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000626#endif
627#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000628 PyStructSequence_SET_ITEM(v, 2,
629 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000630#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000631 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000632#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000633 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
634 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
635 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000636#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000637 PyStructSequence_SET_ITEM(v, 6,
638 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000639#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000640 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000641#endif
642#if SIZEOF_TIME_T > SIZEOF_LONG
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000643 PyStructSequence_SET_ITEM(v, 7,
644 PyLong_FromLongLong((LONG_LONG)st.st_atime));
645 PyStructSequence_SET_ITEM(v, 8,
646 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
647 PyStructSequence_SET_ITEM(v, 9,
648 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000649#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000650 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
651 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
652 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
653#endif
654
655#ifdef HAVE_ST_BLKSIZE
656 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
657 PyInt_FromLong((long)st.st_blksize));
658#endif
659#ifdef HAVE_ST_BLOCKS
660 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
661 PyInt_FromLong((long)st.st_blocks));
662#endif
663#ifdef HAVE_ST_RDEV
664 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
665 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000666#endif
667
668 if (PyErr_Occurred()) {
669 Py_DECREF(v);
670 return NULL;
671 }
672
673 return v;
674}
675
Barry Warsaw53699e91996-12-10 23:23:01 +0000676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000677posix_do_stat(PyObject *self, PyObject *args, char *format,
678 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000679{
Fred Drake699f3522000-06-29 21:12:41 +0000680 STRUCT_STAT st;
Mark Hammondef8b6542001-05-13 08:04:26 +0000681 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000682 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000683
684#ifdef MS_WIN32
685 int pathlen;
686 char pathcopy[MAX_PATH];
687#endif /* MS_WIN32 */
688
Mark Hammondef8b6542001-05-13 08:04:26 +0000689 if (!PyArg_ParseTuple(args, format,
690 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000692
693#ifdef MS_WIN32
694 pathlen = strlen(path);
695 /* the library call can blow up if the file name is too long! */
696 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000697 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000698 errno = ENAMETOOLONG;
699 return posix_error();
700 }
701
702 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000703 /* exception for specific or current drive root */
704 if (!((pathlen == 1) ||
705 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000706 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000707 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000708 {
709 strncpy(pathcopy, path, pathlen);
710 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
711 path = pathcopy;
712 }
713 }
714#endif /* MS_WIN32 */
715
Barry Warsaw53699e91996-12-10 23:23:01 +0000716 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000717 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000718 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000719 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000720 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000721
Mark Hammondef8b6542001-05-13 08:04:26 +0000722 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000723 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000724}
725
726
727/* POSIX methods */
728
Guido van Rossum94f6f721999-01-06 18:42:14 +0000729static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000730"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000731Test for access to a file.";
732
733static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000734posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000735{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000736 char *path;
737 int mode;
738 int res;
739
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000740 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000741 return NULL;
742 Py_BEGIN_ALLOW_THREADS
743 res = access(path, mode);
744 Py_END_ALLOW_THREADS
745 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000746}
747
Guido van Rossumd371ff11999-01-25 16:12:23 +0000748#ifndef F_OK
749#define F_OK 0
750#endif
751#ifndef R_OK
752#define R_OK 4
753#endif
754#ifndef W_OK
755#define W_OK 2
756#endif
757#ifndef X_OK
758#define X_OK 1
759#endif
760
761#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000762static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000763"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000764Return the name of the terminal device connected to 'fd'.";
765
766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000767posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000768{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000769 int id;
770 char *ret;
771
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000772 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000773 return NULL;
774
Guido van Rossum94f6f721999-01-06 18:42:14 +0000775 ret = ttyname(id);
776 if (ret == NULL)
777 return(posix_error());
778 return(PyString_FromString(ret));
779}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000780#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000781
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000782#ifdef HAVE_CTERMID
783static char posix_ctermid__doc__[] =
784"ctermid() -> String\n\
785Return the name of the controlling terminal for this process.";
786
787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000788posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000789{
790 char *ret;
791 char buffer[L_ctermid];
792
793 if (!PyArg_ParseTuple(args, ":ctermid"))
794 return NULL;
795
Greg Wardb48bc172000-03-01 21:51:56 +0000796#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000797 ret = ctermid_r(buffer);
798#else
799 ret = ctermid(buffer);
800#endif
801 if (ret == NULL)
802 return(posix_error());
803 return(PyString_FromString(buffer));
804}
805#endif
806
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000807static char posix_chdir__doc__[] =
808"chdir(path) -> None\n\
809Change the current working directory to the specified path.";
810
Barry Warsaw53699e91996-12-10 23:23:01 +0000811static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000812posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000813{
Mark Hammondef8b6542001-05-13 08:04:26 +0000814 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000815}
816
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000817
818static char posix_chmod__doc__[] =
819"chmod(path, mode) -> None\n\
820Change the access permissions of a file.";
821
Barry Warsaw53699e91996-12-10 23:23:01 +0000822static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000823posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000824{
Mark Hammondef8b6542001-05-13 08:04:26 +0000825 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000826 int i;
827 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000828 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
829 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000830 return NULL;
831 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000832 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000833 Py_END_ALLOW_THREADS
834 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000835 return posix_error_with_allocated_filename(path);
836 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000837 Py_INCREF(Py_None);
838 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000839}
840
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000841
Martin v. Löwis244edc82001-10-04 22:44:26 +0000842#ifdef HAVE_CHROOT
843static char posix_chroot__doc__[] =
844"chroot(path) -> None\n\
845Change root directory to path.";
846
847static PyObject *
848posix_chroot(PyObject *self, PyObject *args)
849{
850 return posix_1str(args, "et:chroot", chroot);
851}
852#endif
853
Guido van Rossum21142a01999-01-08 21:05:37 +0000854#ifdef HAVE_FSYNC
855static char posix_fsync__doc__[] =
856"fsync(fildes) -> None\n\
857force write of file with filedescriptor to disk.";
858
859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000860posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000861{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000862 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000863}
864#endif /* HAVE_FSYNC */
865
866#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000867
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000868#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000869extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
870#endif
871
Guido van Rossum21142a01999-01-08 21:05:37 +0000872static char posix_fdatasync__doc__[] =
873"fdatasync(fildes) -> None\n\
874force write of file with filedescriptor to disk.\n\
875 does not force update of metadata.";
876
877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000878posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000879{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000880 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000881}
882#endif /* HAVE_FDATASYNC */
883
884
Fredrik Lundh10723342000-07-10 16:38:09 +0000885#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000886static char posix_chown__doc__[] =
887"chown(path, uid, gid) -> None\n\
888Change the owner and group id of path to the numeric uid and gid.";
889
Barry Warsaw53699e91996-12-10 23:23:01 +0000890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000891posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000892{
Mark Hammondef8b6542001-05-13 08:04:26 +0000893 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000894 int uid, gid;
895 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000896 if (!PyArg_ParseTuple(args, "etii:chown",
897 Py_FileSystemDefaultEncoding, &path,
898 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000899 return NULL;
900 Py_BEGIN_ALLOW_THREADS
901 res = chown(path, (uid_t) uid, (gid_t) gid);
902 Py_END_ALLOW_THREADS
903 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000904 return posix_error_with_allocated_filename(path);
905 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000906 Py_INCREF(Py_None);
907 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000908}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000909#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000911
Guido van Rossum36bc6801995-06-14 22:54:23 +0000912#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000913static char posix_getcwd__doc__[] =
914"getcwd() -> path\n\
915Return a string representing the current working directory.";
916
Barry Warsaw53699e91996-12-10 23:23:01 +0000917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000918posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000919{
920 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000921 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000922 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000923 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000924 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000925 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000926 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000927 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000928 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000929 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000930}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000931#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000932
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000933
Guido van Rossumb6775db1994-08-01 11:34:53 +0000934#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000935static char posix_link__doc__[] =
936"link(src, dst) -> None\n\
937Create a hard link to a file.";
938
Barry Warsaw53699e91996-12-10 23:23:01 +0000939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000940posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000941{
Mark Hammondef8b6542001-05-13 08:04:26 +0000942 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000943}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000944#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000945
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000946
947static char posix_listdir__doc__[] =
948"listdir(path) -> list_of_strings\n\
949Return a list containing the names of the entries in the directory.\n\
950\n\
951 path: path of directory to list\n\
952\n\
953The list is in arbitrary order. It does not include the special\n\
954entries '.' and '..' even if they are present in the directory.";
955
Barry Warsaw53699e91996-12-10 23:23:01 +0000956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000957posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000958{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000959 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000960 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000961#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000962
Barry Warsaw53699e91996-12-10 23:23:01 +0000963 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000964 HANDLE hFindFile;
965 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000966 /* MAX_PATH characters could mean a bigger encoded string */
967 char namebuf[MAX_PATH*2+5];
968 char *bufptr = namebuf;
969 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000970 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000971
Mark Hammondef8b6542001-05-13 08:04:26 +0000972 if (!PyArg_ParseTuple(args, "et#:listdir",
973 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000974 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000975 ch = namebuf[len-1];
976 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000977 namebuf[len++] = '/';
978 strcpy(namebuf + len, "*.*");
979
Barry Warsaw53699e91996-12-10 23:23:01 +0000980 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000981 return NULL;
982
983 hFindFile = FindFirstFile(namebuf, &FileData);
984 if (hFindFile == INVALID_HANDLE_VALUE) {
985 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000986 if (errno == ERROR_FILE_NOT_FOUND)
987 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000988 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000989 }
990 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000991 if (FileData.cFileName[0] == '.' &&
992 (FileData.cFileName[1] == '\0' ||
993 FileData.cFileName[1] == '.' &&
994 FileData.cFileName[2] == '\0'))
995 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000996 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000997 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000998 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000999 d = NULL;
1000 break;
1001 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001002 if (PyList_Append(d, v) != 0) {
1003 Py_DECREF(v);
1004 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001005 d = NULL;
1006 break;
1007 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001008 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001009 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1010
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001011 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001012 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001013
1014 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001015
Tim Peters0bb44a42000-09-15 07:44:49 +00001016#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001017
1018#ifndef MAX_PATH
1019#define MAX_PATH 250
1020#endif
1021 char *name, *pt;
1022 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001023 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001024 char namebuf[MAX_PATH+5];
1025 struct _find_t ep;
1026
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001027 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001028 return NULL;
1029 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001030 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001031 return NULL;
1032 }
1033 strcpy(namebuf, name);
1034 for (pt = namebuf; *pt; pt++)
1035 if (*pt == '/')
1036 *pt = '\\';
1037 if (namebuf[len-1] != '\\')
1038 namebuf[len++] = '\\';
1039 strcpy(namebuf + len, "*.*");
1040
Barry Warsaw53699e91996-12-10 23:23:01 +00001041 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001042 return NULL;
1043
1044 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001045 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1046 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001047 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001048 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001049 }
1050 do {
1051 if (ep.name[0] == '.' &&
1052 (ep.name[1] == '\0' ||
1053 ep.name[1] == '.' &&
1054 ep.name[2] == '\0'))
1055 continue;
1056 strcpy(namebuf, ep.name);
1057 for (pt = namebuf; *pt; pt++)
1058 if (isupper(*pt))
1059 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001060 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001061 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001062 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001063 d = NULL;
1064 break;
1065 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001066 if (PyList_Append(d, v) != 0) {
1067 Py_DECREF(v);
1068 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001069 d = NULL;
1070 break;
1071 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001072 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001073 } while (_dos_findnext(&ep) == 0);
1074
1075 return d;
1076
Tim Peters0bb44a42000-09-15 07:44:49 +00001077#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001078
1079#ifndef MAX_PATH
1080#define MAX_PATH CCHMAXPATH
1081#endif
1082 char *name, *pt;
1083 int len;
1084 PyObject *d, *v;
1085 char namebuf[MAX_PATH+5];
1086 HDIR hdir = 1;
1087 ULONG srchcnt = 1;
1088 FILEFINDBUF3 ep;
1089 APIRET rc;
1090
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001091 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001092 return NULL;
1093 if (len >= MAX_PATH) {
1094 PyErr_SetString(PyExc_ValueError, "path too long");
1095 return NULL;
1096 }
1097 strcpy(namebuf, name);
1098 for (pt = namebuf; *pt; pt++)
1099 if (*pt == '/')
1100 *pt = '\\';
1101 if (namebuf[len-1] != '\\')
1102 namebuf[len++] = '\\';
1103 strcpy(namebuf + len, "*.*");
1104
1105 if ((d = PyList_New(0)) == NULL)
1106 return NULL;
1107
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001108 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1109 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001110 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001111 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1112 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1113 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001114
1115 if (rc != NO_ERROR) {
1116 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001117 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001118 }
1119
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001120 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001121 do {
1122 if (ep.achName[0] == '.'
1123 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001124 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001125
1126 strcpy(namebuf, ep.achName);
1127
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001128 /* Leave Case of Name Alone -- In Native Form */
1129 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001130
1131 v = PyString_FromString(namebuf);
1132 if (v == NULL) {
1133 Py_DECREF(d);
1134 d = NULL;
1135 break;
1136 }
1137 if (PyList_Append(d, v) != 0) {
1138 Py_DECREF(v);
1139 Py_DECREF(d);
1140 d = NULL;
1141 break;
1142 }
1143 Py_DECREF(v);
1144 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1145 }
1146
1147 return d;
1148#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001149
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001150 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001151 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001152 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001153 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001154 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001155 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001156 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001157 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001158 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001159 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001160 closedir(dirp);
1161 return NULL;
1162 }
1163 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001164 if (ep->d_name[0] == '.' &&
1165 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001166 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001167 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001168 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001169 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001170 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171 d = NULL;
1172 break;
1173 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001174 if (PyList_Append(d, v) != 0) {
1175 Py_DECREF(v);
1176 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001177 d = NULL;
1178 break;
1179 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001180 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001181 }
1182 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001183
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001184 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001185
Tim Peters0bb44a42000-09-15 07:44:49 +00001186#endif /* which OS */
1187} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001188
Mark Hammondef8b6542001-05-13 08:04:26 +00001189#ifdef MS_WIN32
1190/* A helper function for abspath on win32 */
1191static PyObject *
1192posix__getfullpathname(PyObject *self, PyObject *args)
1193{
1194 /* assume encoded strings wont more than double no of chars */
1195 char inbuf[MAX_PATH*2];
1196 char *inbufp = inbuf;
1197 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1198 char outbuf[MAX_PATH*2];
1199 char *temp;
1200 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1201 Py_FileSystemDefaultEncoding, &inbufp,
1202 &insize))
1203 return NULL;
1204 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1205 outbuf, &temp))
1206 return win32_error("GetFullPathName", inbuf);
1207 return PyString_FromString(outbuf);
1208} /* end of posix__getfullpathname */
1209#endif /* MS_WIN32 */
1210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001211static char posix_mkdir__doc__[] =
1212"mkdir(path [, mode=0777]) -> None\n\
1213Create a directory.";
1214
Barry Warsaw53699e91996-12-10 23:23:01 +00001215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001216posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001217{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001218 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001219 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001220 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001221 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1222 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001223 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001224 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001225#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001226 res = mkdir(path);
1227#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001228 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001229#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001230 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001231 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001232 return posix_error_with_allocated_filename(path);
1233 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001234 Py_INCREF(Py_None);
1235 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001236}
1237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001238
Guido van Rossumb6775db1994-08-01 11:34:53 +00001239#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001240#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1241#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1242#include <sys/resource.h>
1243#endif
1244#endif
1245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001246static char posix_nice__doc__[] =
1247"nice(inc) -> new_priority\n\
1248Decrease the priority of process and return new priority.";
1249
Barry Warsaw53699e91996-12-10 23:23:01 +00001250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001251posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001252{
1253 int increment, value;
1254
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001255 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001256 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001257
1258 /* There are two flavours of 'nice': one that returns the new
1259 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001260 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1261 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001262
1263 If we are of the nice family that returns the new priority, we
1264 need to clear errno before the call, and check if errno is filled
1265 before calling posix_error() on a returnvalue of -1, because the
1266 -1 may be the actual new priority! */
1267
1268 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001269 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001270#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001271 if (value == 0)
1272 value = getpriority(PRIO_PROCESS, 0);
1273#endif
1274 if (value == -1 && errno != 0)
1275 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001276 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001277 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001278}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001279#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001281
1282static char posix_rename__doc__[] =
1283"rename(old, new) -> None\n\
1284Rename a file or directory.";
1285
Barry Warsaw53699e91996-12-10 23:23:01 +00001286static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001287posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001288{
Mark Hammondef8b6542001-05-13 08:04:26 +00001289 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001290}
1291
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001292
1293static char posix_rmdir__doc__[] =
1294"rmdir(path) -> None\n\
1295Remove a directory.";
1296
Barry Warsaw53699e91996-12-10 23:23:01 +00001297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001298posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299{
Mark Hammondef8b6542001-05-13 08:04:26 +00001300 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301}
1302
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001303
1304static char posix_stat__doc__[] =
1305"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1306Perform a stat system call on the given path.";
1307
Barry Warsaw53699e91996-12-10 23:23:01 +00001308static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001309posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001310{
Mark Hammondef8b6542001-05-13 08:04:26 +00001311 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312}
1313
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001314
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001315#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001316static char posix_system__doc__[] =
1317"system(command) -> exit_status\n\
1318Execute the command (a string) in a subshell.";
1319
Barry Warsaw53699e91996-12-10 23:23:01 +00001320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001321posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001322{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001323 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001324 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001325 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001327 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001328 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001329 Py_END_ALLOW_THREADS
1330 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001332#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001334
1335static char posix_umask__doc__[] =
1336"umask(new_mask) -> old_mask\n\
1337Set the current numeric umask and return the previous umask.";
1338
Barry Warsaw53699e91996-12-10 23:23:01 +00001339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001340posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341{
1342 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001343 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001345 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346 if (i < 0)
1347 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001348 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001349}
1350
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001351
1352static char posix_unlink__doc__[] =
1353"unlink(path) -> None\n\
1354Remove a file (same as remove(path)).";
1355
1356static char posix_remove__doc__[] =
1357"remove(path) -> None\n\
1358Remove a file (same as unlink(path)).";
1359
Barry Warsaw53699e91996-12-10 23:23:01 +00001360static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001361posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362{
Mark Hammondef8b6542001-05-13 08:04:26 +00001363 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364}
1365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001366
Guido van Rossumb6775db1994-08-01 11:34:53 +00001367#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001368static char posix_uname__doc__[] =
1369"uname() -> (sysname, nodename, release, version, machine)\n\
1370Return a tuple identifying the current operating system.";
1371
Barry Warsaw53699e91996-12-10 23:23:01 +00001372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001373posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001374{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001375 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001376 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001377 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001378 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001379 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001380 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001381 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001382 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001383 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001384 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001385 u.sysname,
1386 u.nodename,
1387 u.release,
1388 u.version,
1389 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001390}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001391#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001393
1394static char posix_utime__doc__[] =
1395"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001396utime(path, None) -> None\n\
1397Set the access and modified time of the file to the given values. If the\n\
1398second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001399
Barry Warsaw53699e91996-12-10 23:23:01 +00001400static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001401posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001402{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001403 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001404 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001405 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001406 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001407
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001408/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001409#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001410 struct utimbuf buf;
1411#define ATIME buf.actime
1412#define MTIME buf.modtime
1413#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001414#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001415 time_t buf[2];
1416#define ATIME buf[0]
1417#define MTIME buf[1]
1418#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001419#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001420
Barry Warsaw3cef8562000-05-01 16:17:24 +00001421 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001422 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001423 if (arg == Py_None) {
1424 /* optional time values not given */
1425 Py_BEGIN_ALLOW_THREADS
1426 res = utime(path, NULL);
1427 Py_END_ALLOW_THREADS
1428 }
1429 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1430 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001431 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001432 return NULL;
1433 }
1434 else {
1435 ATIME = atime;
1436 MTIME = mtime;
1437 Py_BEGIN_ALLOW_THREADS
1438 res = utime(path, UTIME_ARG);
1439 Py_END_ALLOW_THREADS
1440 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001441 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001442 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001443 Py_INCREF(Py_None);
1444 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001445#undef UTIME_ARG
1446#undef ATIME
1447#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001448}
1449
Guido van Rossum85e3b011991-06-03 12:42:10 +00001450
Guido van Rossum3b066191991-06-04 19:40:25 +00001451/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001452
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001453static char posix__exit__doc__[] =
1454"_exit(status)\n\
1455Exit to the system with specified status, without normal exit processing.";
1456
Barry Warsaw53699e91996-12-10 23:23:01 +00001457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001458posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001459{
1460 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001461 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001462 return NULL;
1463 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001464 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001465}
1466
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001467
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001468#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001469static char posix_execv__doc__[] =
1470"execv(path, args)\n\
1471Execute an executable path with arguments, replacing current process.\n\
1472\n\
1473 path: path of executable file\n\
1474 args: tuple or list of strings";
1475
Barry Warsaw53699e91996-12-10 23:23:01 +00001476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001477posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001478{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001479 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001480 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001481 char **argvlist;
1482 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001483 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001484
Guido van Rossum89b33251993-10-22 14:26:06 +00001485 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001486 argv is a list or tuple of strings. */
1487
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001488 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001489 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001490 if (PyList_Check(argv)) {
1491 argc = PyList_Size(argv);
1492 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001493 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001494 else if (PyTuple_Check(argv)) {
1495 argc = PyTuple_Size(argv);
1496 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001497 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001498 else {
Fred Drake661ea262000-10-24 19:57:45 +00001499 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001500 return NULL;
1501 }
1502
1503 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001504 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001505 return NULL;
1506 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001507
Barry Warsaw53699e91996-12-10 23:23:01 +00001508 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001509 if (argvlist == NULL)
1510 return NULL;
1511 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001512 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1513 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001514 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001515 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001516 return NULL;
1517
Guido van Rossum85e3b011991-06-03 12:42:10 +00001518 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001519 }
1520 argvlist[argc] = NULL;
1521
Guido van Rossumb6775db1994-08-01 11:34:53 +00001522#ifdef BAD_EXEC_PROTOTYPES
1523 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001524#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001525 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001526#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001527
Guido van Rossum85e3b011991-06-03 12:42:10 +00001528 /* If we get here it's definitely an error */
1529
Barry Warsaw53699e91996-12-10 23:23:01 +00001530 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001531 return posix_error();
1532}
1533
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001534
1535static char posix_execve__doc__[] =
1536"execve(path, args, env)\n\
1537Execute a path with arguments and environment, replacing current process.\n\
1538\n\
1539 path: path of executable file\n\
1540 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001541 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001542
Barry Warsaw53699e91996-12-10 23:23:01 +00001543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001544posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001545{
1546 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001547 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001548 char **argvlist;
1549 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001550 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001551 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001552 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001553
1554 /* execve has three arguments: (path, argv, env), where
1555 argv is a list or tuple of strings and env is a dictionary
1556 like posix.environ. */
1557
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001558 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001559 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001560 if (PyList_Check(argv)) {
1561 argc = PyList_Size(argv);
1562 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001563 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001564 else if (PyTuple_Check(argv)) {
1565 argc = PyTuple_Size(argv);
1566 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001567 }
1568 else {
Fred Drake661ea262000-10-24 19:57:45 +00001569 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001570 return NULL;
1571 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001572 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001573 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001574 return NULL;
1575 }
1576
Guido van Rossum50422b42000-04-26 20:34:28 +00001577 if (argc == 0) {
1578 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001579 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001580 return NULL;
1581 }
1582
Barry Warsaw53699e91996-12-10 23:23:01 +00001583 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001584 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001585 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001586 return NULL;
1587 }
1588 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001589 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001590 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001591 &argvlist[i]))
1592 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001593 goto fail_1;
1594 }
1595 }
1596 argvlist[argc] = NULL;
1597
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001598 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001599 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001600 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001601 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001602 goto fail_1;
1603 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001604 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001605 keys = PyMapping_Keys(env);
1606 vals = PyMapping_Values(env);
1607 if (!keys || !vals)
1608 goto fail_2;
1609
1610 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001611 char *p, *k, *v;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001612
1613 key = PyList_GetItem(keys, pos);
1614 val = PyList_GetItem(vals, pos);
1615 if (!key || !val)
1616 goto fail_2;
1617
Fred Drake661ea262000-10-24 19:57:45 +00001618 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1619 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001620 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001621 goto fail_2;
1622 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001623
1624#if defined(PYOS_OS2)
1625 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1626 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1627#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001628 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001629 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001630 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001631 goto fail_2;
1632 }
1633 sprintf(p, "%s=%s", k, v);
1634 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001635#if defined(PYOS_OS2)
1636 }
1637#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001638 }
1639 envlist[envc] = 0;
1640
Guido van Rossumb6775db1994-08-01 11:34:53 +00001641
1642#ifdef BAD_EXEC_PROTOTYPES
1643 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001644#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001645 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001646#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001647
1648 /* If we get here it's definitely an error */
1649
1650 (void) posix_error();
1651
1652 fail_2:
1653 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001654 PyMem_DEL(envlist[envc]);
1655 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001656 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001657 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001658 Py_XDECREF(vals);
1659 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001660 return NULL;
1661}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001662#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001664
Guido van Rossuma1065681999-01-25 23:20:23 +00001665#ifdef HAVE_SPAWNV
1666static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001667"spawnv(mode, path, args)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001668Execute an executable path with arguments, replacing current process.\n\
1669\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001670 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001671 path: path of executable file\n\
1672 args: tuple or list of strings";
1673
1674static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001675posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001676{
1677 char *path;
1678 PyObject *argv;
1679 char **argvlist;
1680 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001681 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001682 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001683
1684 /* spawnv has three arguments: (mode, path, argv), where
1685 argv is a list or tuple of strings. */
1686
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001687 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001688 return NULL;
1689 if (PyList_Check(argv)) {
1690 argc = PyList_Size(argv);
1691 getitem = PyList_GetItem;
1692 }
1693 else if (PyTuple_Check(argv)) {
1694 argc = PyTuple_Size(argv);
1695 getitem = PyTuple_GetItem;
1696 }
1697 else {
Fred Drake661ea262000-10-24 19:57:45 +00001698 PyErr_SetString(PyExc_TypeError, "spawmv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001699 return NULL;
1700 }
1701
1702 argvlist = PyMem_NEW(char *, argc+1);
1703 if (argvlist == NULL)
1704 return NULL;
1705 for (i = 0; i < argc; i++) {
1706 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1707 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001708 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001709 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001710 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001711 }
1712 }
1713 argvlist[argc] = NULL;
1714
Guido van Rossum246bc171999-02-01 23:54:31 +00001715 if (mode == _OLD_P_OVERLAY)
1716 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001717 spawnval = _spawnv(mode, path, argvlist);
Guido van Rossuma1065681999-01-25 23:20:23 +00001718
1719 PyMem_DEL(argvlist);
1720
Fred Drake699f3522000-06-29 21:12:41 +00001721 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001722 return posix_error();
1723 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001724#if SIZEOF_LONG == SIZEOF_VOID_P
1725 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001726#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001727 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001728#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001729}
1730
1731
1732static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001733"spawnve(mode, path, args, env)\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001734Execute a path with arguments and environment, replacing current process.\n\
1735\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001736 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001737 path: path of executable file\n\
1738 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001739 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001740
1741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001742posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001743{
1744 char *path;
1745 PyObject *argv, *env;
1746 char **argvlist;
1747 char **envlist;
1748 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1749 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001750 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001751 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001752
1753 /* spawnve has four arguments: (mode, path, argv, env), where
1754 argv is a list or tuple of strings and env is a dictionary
1755 like posix.environ. */
1756
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001757 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001758 return NULL;
1759 if (PyList_Check(argv)) {
1760 argc = PyList_Size(argv);
1761 getitem = PyList_GetItem;
1762 }
1763 else if (PyTuple_Check(argv)) {
1764 argc = PyTuple_Size(argv);
1765 getitem = PyTuple_GetItem;
1766 }
1767 else {
Fred Drake661ea262000-10-24 19:57:45 +00001768 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001769 return NULL;
1770 }
1771 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001772 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001773 return NULL;
1774 }
1775
1776 argvlist = PyMem_NEW(char *, argc+1);
1777 if (argvlist == NULL) {
1778 PyErr_NoMemory();
1779 return NULL;
1780 }
1781 for (i = 0; i < argc; i++) {
1782 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001783 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001784 &argvlist[i]))
1785 {
1786 goto fail_1;
1787 }
1788 }
1789 argvlist[argc] = NULL;
1790
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001791 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001792 envlist = PyMem_NEW(char *, i + 1);
1793 if (envlist == NULL) {
1794 PyErr_NoMemory();
1795 goto fail_1;
1796 }
1797 envc = 0;
1798 keys = PyMapping_Keys(env);
1799 vals = PyMapping_Values(env);
1800 if (!keys || !vals)
1801 goto fail_2;
1802
1803 for (pos = 0; pos < i; pos++) {
1804 char *p, *k, *v;
1805
1806 key = PyList_GetItem(keys, pos);
1807 val = PyList_GetItem(vals, pos);
1808 if (!key || !val)
1809 goto fail_2;
1810
Fred Drake661ea262000-10-24 19:57:45 +00001811 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1812 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001813 {
1814 goto fail_2;
1815 }
1816 p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1817 if (p == NULL) {
1818 PyErr_NoMemory();
1819 goto fail_2;
1820 }
1821 sprintf(p, "%s=%s", k, v);
1822 envlist[envc++] = p;
1823 }
1824 envlist[envc] = 0;
1825
Guido van Rossum246bc171999-02-01 23:54:31 +00001826 if (mode == _OLD_P_OVERLAY)
1827 mode = _P_OVERLAY;
Fred Drake699f3522000-06-29 21:12:41 +00001828 spawnval = _spawnve(mode, path, argvlist, envlist);
1829 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001830 (void) posix_error();
1831 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001832#if SIZEOF_LONG == SIZEOF_VOID_P
1833 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001834#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001835 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001836#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001837
1838 fail_2:
1839 while (--envc >= 0)
1840 PyMem_DEL(envlist[envc]);
1841 PyMem_DEL(envlist);
1842 fail_1:
1843 PyMem_DEL(argvlist);
1844 Py_XDECREF(vals);
1845 Py_XDECREF(keys);
1846 return res;
1847}
1848#endif /* HAVE_SPAWNV */
1849
1850
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001851#ifdef HAVE_FORK1
1852static char posix_fork1__doc__[] =
1853"fork1() -> pid\n\
1854Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1855\n\
1856Return 0 to child process and PID of child to parent process.";
1857
1858static PyObject *
1859posix_fork1(self, args)
1860 PyObject *self;
1861 PyObject *args;
1862{
1863 int pid;
1864 if (!PyArg_ParseTuple(args, ":fork1"))
1865 return NULL;
1866 pid = fork1();
1867 if (pid == -1)
1868 return posix_error();
1869 PyOS_AfterFork();
1870 return PyInt_FromLong((long)pid);
1871}
1872#endif
1873
1874
Guido van Rossumad0ee831995-03-01 10:34:45 +00001875#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001876static char posix_fork__doc__[] =
1877"fork() -> pid\n\
1878Fork a child process.\n\
1879\n\
1880Return 0 to child process and PID of child to parent process.";
1881
Barry Warsaw53699e91996-12-10 23:23:01 +00001882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001883posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001884{
1885 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001886 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001887 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001888 pid = fork();
1889 if (pid == -1)
1890 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001891 if (pid == 0)
1892 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001893 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001894}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001895#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001896
Fred Drake8cef4cf2000-06-28 16:40:38 +00001897#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1898#ifdef HAVE_PTY_H
1899#include <pty.h>
1900#else
1901#ifdef HAVE_LIBUTIL_H
1902#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001903#endif /* HAVE_LIBUTIL_H */
1904#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001905#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001906
Thomas Wouters70c21a12000-07-14 14:28:33 +00001907#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001908static char posix_openpty__doc__[] =
1909"openpty() -> (master_fd, slave_fd)\n\
1910Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1911
1912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001913posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001914{
1915 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001916#ifndef HAVE_OPENPTY
1917 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001918#endif
1919
Fred Drake8cef4cf2000-06-28 16:40:38 +00001920 if (!PyArg_ParseTuple(args, ":openpty"))
1921 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001922
1923#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001924 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1925 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001926#else
1927 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1928 if (slave_name == NULL)
1929 return posix_error();
1930
1931 slave_fd = open(slave_name, O_RDWR);
1932 if (slave_fd < 0)
1933 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001934#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001935
Fred Drake8cef4cf2000-06-28 16:40:38 +00001936 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001937
Fred Drake8cef4cf2000-06-28 16:40:38 +00001938}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001939#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001940
1941#ifdef HAVE_FORKPTY
1942static char posix_forkpty__doc__[] =
1943"forkpty() -> (pid, master_fd)\n\
1944Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1945Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1946To both, return fd of newly opened pseudo-terminal.\n";
1947
1948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001949posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001950{
1951 int master_fd, pid;
1952
1953 if (!PyArg_ParseTuple(args, ":forkpty"))
1954 return NULL;
1955 pid = forkpty(&master_fd, NULL, NULL, NULL);
1956 if (pid == -1)
1957 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001958 if (pid == 0)
1959 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001960 return Py_BuildValue("(ii)", pid, master_fd);
1961}
1962#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001963
Guido van Rossumad0ee831995-03-01 10:34:45 +00001964#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001965static char posix_getegid__doc__[] =
1966"getegid() -> egid\n\
1967Return the current process's effective group id.";
1968
Barry Warsaw53699e91996-12-10 23:23:01 +00001969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001970posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001971{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001972 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001973 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001974 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001975}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001976#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001977
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001978
Guido van Rossumad0ee831995-03-01 10:34:45 +00001979#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001980static char posix_geteuid__doc__[] =
1981"geteuid() -> euid\n\
1982Return the current process's effective user id.";
1983
Barry Warsaw53699e91996-12-10 23:23:01 +00001984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001985posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001986{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001987 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001988 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001989 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001990}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001991#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001993
Guido van Rossumad0ee831995-03-01 10:34:45 +00001994#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001995static char posix_getgid__doc__[] =
1996"getgid() -> gid\n\
1997Return the current process's group id.";
1998
Barry Warsaw53699e91996-12-10 23:23:01 +00001999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002000posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002001{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002002 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002003 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002004 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002005}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002006#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002008
2009static char posix_getpid__doc__[] =
2010"getpid() -> pid\n\
2011Return the current process id";
2012
Barry Warsaw53699e91996-12-10 23:23:01 +00002013static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002014posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002015{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002016 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002017 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002018 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002019}
2020
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002021
Fred Drakec9680921999-12-13 16:37:25 +00002022#ifdef HAVE_GETGROUPS
2023static char posix_getgroups__doc__[] = "\
2024getgroups() -> list of group IDs\n\
2025Return list of supplemental group IDs for the process.";
2026
2027static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002028posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002029{
2030 PyObject *result = NULL;
2031
2032 if (PyArg_ParseTuple(args, ":getgroups")) {
2033#ifdef NGROUPS_MAX
2034#define MAX_GROUPS NGROUPS_MAX
2035#else
2036 /* defined to be 16 on Solaris7, so this should be a small number */
2037#define MAX_GROUPS 64
2038#endif
2039 gid_t grouplist[MAX_GROUPS];
2040 int n;
2041
2042 n = getgroups(MAX_GROUPS, grouplist);
2043 if (n < 0)
2044 posix_error();
2045 else {
2046 result = PyList_New(n);
2047 if (result != NULL) {
2048 PyObject *o;
2049 int i;
2050 for (i = 0; i < n; ++i) {
2051 o = PyInt_FromLong((long)grouplist[i]);
2052 if (o == NULL) {
2053 Py_DECREF(result);
2054 result = NULL;
2055 break;
2056 }
2057 PyList_SET_ITEM(result, i, o);
2058 }
2059 }
2060 }
2061 }
2062 return result;
2063}
2064#endif
2065
Guido van Rossumb6775db1994-08-01 11:34:53 +00002066#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002067static char posix_getpgrp__doc__[] =
2068"getpgrp() -> pgrp\n\
2069Return the current process group id.";
2070
Barry Warsaw53699e91996-12-10 23:23:01 +00002071static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002072posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002073{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002074 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002075 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002076#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002077 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002078#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002079 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002080#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002081}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002082#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002084
Guido van Rossumb6775db1994-08-01 11:34:53 +00002085#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002086static char posix_setpgrp__doc__[] =
2087"setpgrp() -> None\n\
2088Make this process a session leader.";
2089
Barry Warsaw53699e91996-12-10 23:23:01 +00002090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002091posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002092{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002093 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002094 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002095#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002096 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002097#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002098 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002099#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002100 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002101 Py_INCREF(Py_None);
2102 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002103}
2104
Guido van Rossumb6775db1994-08-01 11:34:53 +00002105#endif /* HAVE_SETPGRP */
2106
Guido van Rossumad0ee831995-03-01 10:34:45 +00002107#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002108static char posix_getppid__doc__[] =
2109"getppid() -> ppid\n\
2110Return the parent's process id.";
2111
Barry Warsaw53699e91996-12-10 23:23:01 +00002112static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002113posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002114{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002115 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002116 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002117 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002118}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002119#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002120
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002121
Fred Drake12c6e2d1999-12-14 21:25:03 +00002122#ifdef HAVE_GETLOGIN
2123static char posix_getlogin__doc__[] = "\
2124getlogin() -> string\n\
2125Return the actual login name.";
2126
2127static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002128posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002129{
2130 PyObject *result = NULL;
2131
2132 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002133 char *name;
2134 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002135
Fred Drakea30680b2000-12-06 21:24:28 +00002136 errno = 0;
2137 name = getlogin();
2138 if (name == NULL) {
2139 if (errno)
2140 posix_error();
2141 else
2142 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002143 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002144 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002145 else
2146 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002147 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002148 }
2149 return result;
2150}
2151#endif
2152
Guido van Rossumad0ee831995-03-01 10:34:45 +00002153#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002154static char posix_getuid__doc__[] =
2155"getuid() -> uid\n\
2156Return the current process's user id.";
2157
Barry Warsaw53699e91996-12-10 23:23:01 +00002158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002159posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002160{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002161 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002162 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002163 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002164}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002165#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002167
Guido van Rossumad0ee831995-03-01 10:34:45 +00002168#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002169static char posix_kill__doc__[] =
2170"kill(pid, sig) -> None\n\
2171Kill a process with a signal.";
2172
Barry Warsaw53699e91996-12-10 23:23:01 +00002173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002174posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002175{
2176 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002177 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002178 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002179#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002180 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2181 APIRET rc;
2182 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002183 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002184
2185 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2186 APIRET rc;
2187 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002188 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002189
2190 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002191 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002192#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002193 if (kill(pid, sig) == -1)
2194 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002195#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002196 Py_INCREF(Py_None);
2197 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002198}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002199#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002200
Guido van Rossumc0125471996-06-28 18:55:32 +00002201#ifdef HAVE_PLOCK
2202
2203#ifdef HAVE_SYS_LOCK_H
2204#include <sys/lock.h>
2205#endif
2206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002207static char posix_plock__doc__[] =
2208"plock(op) -> None\n\
2209Lock program segments into memory.";
2210
Barry Warsaw53699e91996-12-10 23:23:01 +00002211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002212posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002213{
2214 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002215 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002216 return NULL;
2217 if (plock(op) == -1)
2218 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002219 Py_INCREF(Py_None);
2220 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002221}
2222#endif
2223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002224
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002225#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002226static char posix_popen__doc__[] =
2227"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2228Open a pipe to/from a command returning a file object.";
2229
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002230#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002231static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002232async_system(const char *command)
2233{
2234 char *p, errormsg[256], args[1024];
2235 RESULTCODES rcodes;
2236 APIRET rc;
2237 char *shell = getenv("COMSPEC");
2238 if (!shell)
2239 shell = "cmd";
2240
2241 strcpy(args, shell);
2242 p = &args[ strlen(args)+1 ];
2243 strcpy(p, "/c ");
2244 strcat(p, command);
2245 p += strlen(p) + 1;
2246 *p = '\0';
2247
2248 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002249 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002250 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002251 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002252 &rcodes, shell);
2253 return rc;
2254}
2255
Guido van Rossumd48f2521997-12-05 22:19:34 +00002256static FILE *
2257popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002258{
2259 HFILE rhan, whan;
2260 FILE *retfd = NULL;
2261 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2262
Guido van Rossumd48f2521997-12-05 22:19:34 +00002263 if (rc != NO_ERROR) {
2264 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002265 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002266 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002267
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002268 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2269 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002270
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002271 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2272 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002273
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002274 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2275 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002276
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002277 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002278 }
2279
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002280 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2281 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002282
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002283 if (rc == NO_ERROR)
2284 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2285
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002286 close(oldfd); /* And Close Saved STDOUT Handle */
2287 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002288
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002289 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2290 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002291
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002292 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2293 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002294
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002295 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2296 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002297
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002298 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002299 }
2300
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002301 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2302 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002303
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002304 if (rc == NO_ERROR)
2305 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2306
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002307 close(oldfd); /* And Close Saved STDIN Handle */
2308 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002309
Guido van Rossumd48f2521997-12-05 22:19:34 +00002310 } else {
2311 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002312 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002313 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002314}
2315
2316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002317posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002318{
2319 char *name;
2320 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002321 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002322 FILE *fp;
2323 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002324 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002325 return NULL;
2326 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002327 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002328 Py_END_ALLOW_THREADS
2329 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002330 return os2_error(err);
2331
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002332 f = PyFile_FromFile(fp, name, mode, fclose);
2333 if (f != NULL)
2334 PyFile_SetBufSize(f, bufsize);
2335 return f;
2336}
2337
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002338#elif defined(MS_WIN32)
2339
2340/*
2341 * Portable 'popen' replacement for Win32.
2342 *
2343 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2344 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002345 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002346 */
2347
2348#include <malloc.h>
2349#include <io.h>
2350#include <fcntl.h>
2351
2352/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2353#define POPEN_1 1
2354#define POPEN_2 2
2355#define POPEN_3 3
2356#define POPEN_4 4
2357
2358static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002359static int _PyPclose(FILE *file);
2360
2361/*
2362 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002363 * for use when retrieving the process exit code. See _PyPclose() below
2364 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002365 */
2366static PyObject *_PyPopenProcs = NULL;
2367
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002368
2369/* popen that works from a GUI.
2370 *
2371 * The result of this function is a pipe (file) connected to the
2372 * processes stdin or stdout, depending on the requested mode.
2373 */
2374
2375static PyObject *
2376posix_popen(PyObject *self, PyObject *args)
2377{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002378 PyObject *f, *s;
2379 int tm = 0;
2380
2381 char *cmdstring;
2382 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002383 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002384 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002385 return NULL;
2386
2387 s = PyTuple_New(0);
2388
2389 if (*mode == 'r')
2390 tm = _O_RDONLY;
2391 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002392 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002393 return NULL;
2394 } else
2395 tm = _O_WRONLY;
2396
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002397 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002398 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002399 return NULL;
2400 }
2401
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002402 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002403 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002404 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002405 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002406 else
2407 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2408
2409 return f;
2410}
2411
2412/* Variation on win32pipe.popen
2413 *
2414 * The result of this function is a pipe (file) connected to the
2415 * process's stdin, and a pipe connected to the process's stdout.
2416 */
2417
2418static PyObject *
2419win32_popen2(PyObject *self, PyObject *args)
2420{
2421 PyObject *f;
2422 int tm=0;
2423
2424 char *cmdstring;
2425 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002426 int bufsize = -1;
2427 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002428 return NULL;
2429
2430 if (*mode == 't')
2431 tm = _O_TEXT;
2432 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002433 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002434 return NULL;
2435 } else
2436 tm = _O_BINARY;
2437
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002438 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002439 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002440 return NULL;
2441 }
2442
2443 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002444
2445 return f;
2446}
2447
2448/*
2449 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002450 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002451 * The result of this function is 3 pipes - the process's stdin,
2452 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002453 */
2454
2455static PyObject *
2456win32_popen3(PyObject *self, PyObject *args)
2457{
2458 PyObject *f;
2459 int tm = 0;
2460
2461 char *cmdstring;
2462 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002463 int bufsize = -1;
2464 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002465 return NULL;
2466
2467 if (*mode == 't')
2468 tm = _O_TEXT;
2469 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002470 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002471 return NULL;
2472 } else
2473 tm = _O_BINARY;
2474
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002475 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002476 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002477 return NULL;
2478 }
2479
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002480 f = _PyPopen(cmdstring, tm, POPEN_3);
2481
2482 return f;
2483}
2484
2485/*
2486 * Variation on win32pipe.popen
2487 *
2488 * The result of this function is 2 pipes - the processes stdin,
2489 * and stdout+stderr combined as a single pipe.
2490 */
2491
2492static PyObject *
2493win32_popen4(PyObject *self, PyObject *args)
2494{
2495 PyObject *f;
2496 int tm = 0;
2497
2498 char *cmdstring;
2499 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002500 int bufsize = -1;
2501 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002502 return NULL;
2503
2504 if (*mode == 't')
2505 tm = _O_TEXT;
2506 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002507 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002508 return NULL;
2509 } else
2510 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002511
2512 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002513 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002514 return NULL;
2515 }
2516
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002517 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002518
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002519 return f;
2520}
2521
Mark Hammond08501372001-01-31 07:30:29 +00002522static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002523_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002524 HANDLE hStdin,
2525 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002526 HANDLE hStderr,
2527 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002528{
2529 PROCESS_INFORMATION piProcInfo;
2530 STARTUPINFO siStartInfo;
2531 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002532 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002533 int i;
2534 int x;
2535
2536 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002537 char *comshell;
2538
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002539 s1 = (char *)_alloca(i);
2540 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2541 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002542
2543 /* Explicitly check if we are using COMMAND.COM. If we are
2544 * then use the w9xpopen hack.
2545 */
2546 comshell = s1 + x;
2547 while (comshell >= s1 && *comshell != '\\')
2548 --comshell;
2549 ++comshell;
2550
2551 if (GetVersion() < 0x80000000 &&
2552 _stricmp(comshell, "command.com") != 0) {
2553 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002554 x = i + strlen(s3) + strlen(cmdstring) + 1;
2555 s2 = (char *)_alloca(x);
2556 ZeroMemory(s2, x);
2557 sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2558 }
2559 else {
2560 /*
Tim Peters402d5982001-08-27 06:37:48 +00002561 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2562 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002563 */
Mark Hammond08501372001-01-31 07:30:29 +00002564 char modulepath[_MAX_PATH];
2565 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002566 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2567 for (i = x = 0; modulepath[i]; i++)
2568 if (modulepath[i] == '\\')
2569 x = i+1;
2570 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002571 /* Create the full-name to w9xpopen, so we can test it exists */
2572 strncat(modulepath,
2573 szConsoleSpawn,
2574 (sizeof(modulepath)/sizeof(modulepath[0]))
2575 -strlen(modulepath));
2576 if (stat(modulepath, &statinfo) != 0) {
2577 /* Eeek - file-not-found - possibly an embedding
2578 situation - see if we can locate it in sys.prefix
2579 */
2580 strncpy(modulepath,
2581 Py_GetExecPrefix(),
2582 sizeof(modulepath)/sizeof(modulepath[0]));
2583 if (modulepath[strlen(modulepath)-1] != '\\')
2584 strcat(modulepath, "\\");
2585 strncat(modulepath,
2586 szConsoleSpawn,
2587 (sizeof(modulepath)/sizeof(modulepath[0]))
2588 -strlen(modulepath));
2589 /* No where else to look - raise an easily identifiable
2590 error, rather than leaving Windows to report
2591 "file not found" - as the user is probably blissfully
2592 unaware this shim EXE is used, and it will confuse them.
2593 (well, it confused me for a while ;-)
2594 */
2595 if (stat(modulepath, &statinfo) != 0) {
2596 PyErr_Format(PyExc_RuntimeError,
2597 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002598 "for popen to work with your shell "
2599 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002600 szConsoleSpawn);
2601 return FALSE;
2602 }
2603 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002604 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2605 strlen(modulepath) +
2606 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002607
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002608 s2 = (char *)_alloca(x);
2609 ZeroMemory(s2, x);
2610 sprintf(
2611 s2,
Mark Hammond08501372001-01-31 07:30:29 +00002612 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002613 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002614 s1,
2615 s3,
2616 cmdstring);
2617 }
2618 }
2619
2620 /* Could be an else here to try cmd.exe / command.com in the path
2621 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002622 else {
Tim Peters402d5982001-08-27 06:37:48 +00002623 PyErr_SetString(PyExc_RuntimeError,
2624 "Cannot locate a COMSPEC environment variable to "
2625 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002626 return FALSE;
2627 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002628
2629 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2630 siStartInfo.cb = sizeof(STARTUPINFO);
2631 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2632 siStartInfo.hStdInput = hStdin;
2633 siStartInfo.hStdOutput = hStdout;
2634 siStartInfo.hStdError = hStderr;
2635 siStartInfo.wShowWindow = SW_HIDE;
2636
2637 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002638 s2,
2639 NULL,
2640 NULL,
2641 TRUE,
2642 CREATE_NEW_CONSOLE,
2643 NULL,
2644 NULL,
2645 &siStartInfo,
2646 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002647 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002648 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002649
Mark Hammondb37a3732000-08-14 04:47:33 +00002650 /* Return process handle */
2651 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002652 return TRUE;
2653 }
Tim Peters402d5982001-08-27 06:37:48 +00002654 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002655 return FALSE;
2656}
2657
2658/* The following code is based off of KB: Q190351 */
2659
2660static PyObject *
2661_PyPopen(char *cmdstring, int mode, int n)
2662{
2663 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2664 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002665 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002666
2667 SECURITY_ATTRIBUTES saAttr;
2668 BOOL fSuccess;
2669 int fd1, fd2, fd3;
2670 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002671 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002672 PyObject *f;
2673
2674 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2675 saAttr.bInheritHandle = TRUE;
2676 saAttr.lpSecurityDescriptor = NULL;
2677
2678 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2679 return win32_error("CreatePipe", NULL);
2680
2681 /* Create new output read handle and the input write handle. Set
2682 * the inheritance properties to FALSE. Otherwise, the child inherits
2683 * the these handles; resulting in non-closeable handles to the pipes
2684 * being created. */
2685 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002686 GetCurrentProcess(), &hChildStdinWrDup, 0,
2687 FALSE,
2688 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002689 if (!fSuccess)
2690 return win32_error("DuplicateHandle", NULL);
2691
2692 /* Close the inheritable version of ChildStdin
2693 that we're using. */
2694 CloseHandle(hChildStdinWr);
2695
2696 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2697 return win32_error("CreatePipe", NULL);
2698
2699 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002700 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2701 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002702 if (!fSuccess)
2703 return win32_error("DuplicateHandle", NULL);
2704
2705 /* Close the inheritable version of ChildStdout
2706 that we're using. */
2707 CloseHandle(hChildStdoutRd);
2708
2709 if (n != POPEN_4) {
2710 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2711 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002712 fSuccess = DuplicateHandle(GetCurrentProcess(),
2713 hChildStderrRd,
2714 GetCurrentProcess(),
2715 &hChildStderrRdDup, 0,
2716 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002717 if (!fSuccess)
2718 return win32_error("DuplicateHandle", NULL);
2719 /* Close the inheritable version of ChildStdErr that we're using. */
2720 CloseHandle(hChildStderrRd);
2721 }
2722
2723 switch (n) {
2724 case POPEN_1:
2725 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2726 case _O_WRONLY | _O_TEXT:
2727 /* Case for writing to child Stdin in text mode. */
2728 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2729 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002730 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002731 PyFile_SetBufSize(f, 0);
2732 /* We don't care about these pipes anymore, so close them. */
2733 CloseHandle(hChildStdoutRdDup);
2734 CloseHandle(hChildStderrRdDup);
2735 break;
2736
2737 case _O_RDONLY | _O_TEXT:
2738 /* Case for reading from child Stdout in text mode. */
2739 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2740 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002741 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002742 PyFile_SetBufSize(f, 0);
2743 /* We don't care about these pipes anymore, so close them. */
2744 CloseHandle(hChildStdinWrDup);
2745 CloseHandle(hChildStderrRdDup);
2746 break;
2747
2748 case _O_RDONLY | _O_BINARY:
2749 /* Case for readinig from child Stdout in binary mode. */
2750 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2751 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002752 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002753 PyFile_SetBufSize(f, 0);
2754 /* We don't care about these pipes anymore, so close them. */
2755 CloseHandle(hChildStdinWrDup);
2756 CloseHandle(hChildStderrRdDup);
2757 break;
2758
2759 case _O_WRONLY | _O_BINARY:
2760 /* Case for writing to child Stdin in binary mode. */
2761 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2762 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002763 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002764 PyFile_SetBufSize(f, 0);
2765 /* We don't care about these pipes anymore, so close them. */
2766 CloseHandle(hChildStdoutRdDup);
2767 CloseHandle(hChildStderrRdDup);
2768 break;
2769 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002770 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002771 break;
2772
2773 case POPEN_2:
2774 case POPEN_4:
2775 {
2776 char *m1, *m2;
2777 PyObject *p1, *p2;
2778
2779 if (mode && _O_TEXT) {
2780 m1 = "r";
2781 m2 = "w";
2782 } else {
2783 m1 = "rb";
2784 m2 = "wb";
2785 }
2786
2787 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2788 f1 = _fdopen(fd1, m2);
2789 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2790 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002791 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002792 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002793 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002794 PyFile_SetBufSize(p2, 0);
2795
2796 if (n != 4)
2797 CloseHandle(hChildStderrRdDup);
2798
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002799 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002800 Py_XDECREF(p1);
2801 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002802 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002803 break;
2804 }
2805
2806 case POPEN_3:
2807 {
2808 char *m1, *m2;
2809 PyObject *p1, *p2, *p3;
2810
2811 if (mode && _O_TEXT) {
2812 m1 = "r";
2813 m2 = "w";
2814 } else {
2815 m1 = "rb";
2816 m2 = "wb";
2817 }
2818
2819 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2820 f1 = _fdopen(fd1, m2);
2821 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2822 f2 = _fdopen(fd2, m1);
2823 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2824 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002825 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002826 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2827 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002828 PyFile_SetBufSize(p1, 0);
2829 PyFile_SetBufSize(p2, 0);
2830 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002831 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002832 Py_XDECREF(p1);
2833 Py_XDECREF(p2);
2834 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002835 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002836 break;
2837 }
2838 }
2839
2840 if (n == POPEN_4) {
2841 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002842 hChildStdinRd,
2843 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002844 hChildStdoutWr,
2845 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002846 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002847 }
2848 else {
2849 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002850 hChildStdinRd,
2851 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002852 hChildStderrWr,
2853 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002854 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002855 }
2856
Mark Hammondb37a3732000-08-14 04:47:33 +00002857 /*
2858 * Insert the files we've created into the process dictionary
2859 * all referencing the list with the process handle and the
2860 * initial number of files (see description below in _PyPclose).
2861 * Since if _PyPclose later tried to wait on a process when all
2862 * handles weren't closed, it could create a deadlock with the
2863 * child, we spend some energy here to try to ensure that we
2864 * either insert all file handles into the dictionary or none
2865 * at all. It's a little clumsy with the various popen modes
2866 * and variable number of files involved.
2867 */
2868 if (!_PyPopenProcs) {
2869 _PyPopenProcs = PyDict_New();
2870 }
2871
2872 if (_PyPopenProcs) {
2873 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2874 int ins_rc[3];
2875
2876 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2877 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2878
2879 procObj = PyList_New(2);
2880 hProcessObj = PyLong_FromVoidPtr(hProcess);
2881 intObj = PyInt_FromLong(file_count);
2882
2883 if (procObj && hProcessObj && intObj) {
2884 PyList_SetItem(procObj,0,hProcessObj);
2885 PyList_SetItem(procObj,1,intObj);
2886
2887 fileObj[0] = PyLong_FromVoidPtr(f1);
2888 if (fileObj[0]) {
2889 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2890 fileObj[0],
2891 procObj);
2892 }
2893 if (file_count >= 2) {
2894 fileObj[1] = PyLong_FromVoidPtr(f2);
2895 if (fileObj[1]) {
2896 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2897 fileObj[1],
2898 procObj);
2899 }
2900 }
2901 if (file_count >= 3) {
2902 fileObj[2] = PyLong_FromVoidPtr(f3);
2903 if (fileObj[2]) {
2904 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2905 fileObj[2],
2906 procObj);
2907 }
2908 }
2909
2910 if (ins_rc[0] < 0 || !fileObj[0] ||
2911 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2912 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2913 /* Something failed - remove any dictionary
2914 * entries that did make it.
2915 */
2916 if (!ins_rc[0] && fileObj[0]) {
2917 PyDict_DelItem(_PyPopenProcs,
2918 fileObj[0]);
2919 }
2920 if (!ins_rc[1] && fileObj[1]) {
2921 PyDict_DelItem(_PyPopenProcs,
2922 fileObj[1]);
2923 }
2924 if (!ins_rc[2] && fileObj[2]) {
2925 PyDict_DelItem(_PyPopenProcs,
2926 fileObj[2]);
2927 }
2928 }
2929 }
2930
2931 /*
2932 * Clean up our localized references for the dictionary keys
2933 * and value since PyDict_SetItem will Py_INCREF any copies
2934 * that got placed in the dictionary.
2935 */
2936 Py_XDECREF(procObj);
2937 Py_XDECREF(fileObj[0]);
2938 Py_XDECREF(fileObj[1]);
2939 Py_XDECREF(fileObj[2]);
2940 }
2941
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002942 /* Child is launched. Close the parents copy of those pipe
2943 * handles that only the child should have open. You need to
2944 * make sure that no handles to the write end of the output pipe
2945 * are maintained in this process or else the pipe will not close
2946 * when the child process exits and the ReadFile will hang. */
2947
2948 if (!CloseHandle(hChildStdinRd))
2949 return win32_error("CloseHandle", NULL);
2950
2951 if (!CloseHandle(hChildStdoutWr))
2952 return win32_error("CloseHandle", NULL);
2953
2954 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2955 return win32_error("CloseHandle", NULL);
2956
2957 return f;
2958}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002959
2960/*
2961 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2962 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002963 *
2964 * This function uses the _PyPopenProcs dictionary in order to map the
2965 * input file pointer to information about the process that was
2966 * originally created by the popen* call that created the file pointer.
2967 * The dictionary uses the file pointer as a key (with one entry
2968 * inserted for each file returned by the original popen* call) and a
2969 * single list object as the value for all files from a single call.
2970 * The list object contains the Win32 process handle at [0], and a file
2971 * count at [1], which is initialized to the total number of file
2972 * handles using that list.
2973 *
2974 * This function closes whichever handle it is passed, and decrements
2975 * the file count in the dictionary for the process handle pointed to
2976 * by this file. On the last close (when the file count reaches zero),
2977 * this function will wait for the child process and then return its
2978 * exit code as the result of the close() operation. This permits the
2979 * files to be closed in any order - it is always the close() of the
2980 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002981 */
Tim Peters736aa322000-09-01 06:51:24 +00002982
2983 /* RED_FLAG 31-Aug-2000 Tim
2984 * This is always called (today!) between a pair of
2985 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2986 * macros. So the thread running this has no valid thread state, as
2987 * far as Python is concerned. However, this calls some Python API
2988 * functions that cannot be called safely without a valid thread
2989 * state, in particular PyDict_GetItem.
2990 * As a temporary hack (although it may last for years ...), we
2991 * *rely* on not having a valid thread state in this function, in
2992 * order to create our own "from scratch".
2993 * This will deadlock if _PyPclose is ever called by a thread
2994 * holding the global lock.
2995 */
2996
Fredrik Lundh56055a42000-07-23 19:47:12 +00002997static int _PyPclose(FILE *file)
2998{
Fredrik Lundh20318932000-07-26 17:29:12 +00002999 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003000 DWORD exit_code;
3001 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003002 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3003 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003004#ifdef WITH_THREAD
3005 PyInterpreterState* pInterpreterState;
3006 PyThreadState* pThreadState;
3007#endif
3008
Fredrik Lundh20318932000-07-26 17:29:12 +00003009 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003010 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003011 */
3012 result = fclose(file);
3013
Tim Peters736aa322000-09-01 06:51:24 +00003014#ifdef WITH_THREAD
3015 /* Bootstrap a valid thread state into existence. */
3016 pInterpreterState = PyInterpreterState_New();
3017 if (!pInterpreterState) {
3018 /* Well, we're hosed now! We don't have a thread
3019 * state, so can't call a nice error routine, or raise
3020 * an exception. Just die.
3021 */
3022 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003023 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003024 return -1; /* unreachable */
3025 }
3026 pThreadState = PyThreadState_New(pInterpreterState);
3027 if (!pThreadState) {
3028 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003029 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003030 return -1; /* unreachable */
3031 }
3032 /* Grab the global lock. Note that this will deadlock if the
3033 * current thread already has the lock! (see RED_FLAG comments
3034 * before this function)
3035 */
3036 PyEval_RestoreThread(pThreadState);
3037#endif
3038
Fredrik Lundh56055a42000-07-23 19:47:12 +00003039 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003040 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3041 (procObj = PyDict_GetItem(_PyPopenProcs,
3042 fileObj)) != NULL &&
3043 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3044 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3045
3046 hProcess = PyLong_AsVoidPtr(hProcessObj);
3047 file_count = PyInt_AsLong(intObj);
3048
3049 if (file_count > 1) {
3050 /* Still other files referencing process */
3051 file_count--;
3052 PyList_SetItem(procObj,1,
3053 PyInt_FromLong(file_count));
3054 } else {
3055 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003056 if (result != EOF &&
3057 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3058 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003059 /* Possible truncation here in 16-bit environments, but
3060 * real exit codes are just the lower byte in any event.
3061 */
3062 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003063 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003064 /* Indicate failure - this will cause the file object
3065 * to raise an I/O error and translate the last Win32
3066 * error code from errno. We do have a problem with
3067 * last errors that overlap the normal errno table,
3068 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003069 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003070 if (result != EOF) {
3071 /* If the error wasn't from the fclose(), then
3072 * set errno for the file object error handling.
3073 */
3074 errno = GetLastError();
3075 }
3076 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003077 }
3078
3079 /* Free up the native handle at this point */
3080 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003081 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003082
Mark Hammondb37a3732000-08-14 04:47:33 +00003083 /* Remove this file pointer from dictionary */
3084 PyDict_DelItem(_PyPopenProcs, fileObj);
3085
3086 if (PyDict_Size(_PyPopenProcs) == 0) {
3087 Py_DECREF(_PyPopenProcs);
3088 _PyPopenProcs = NULL;
3089 }
3090
3091 } /* if object retrieval ok */
3092
3093 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003094 } /* if _PyPopenProcs */
3095
Tim Peters736aa322000-09-01 06:51:24 +00003096#ifdef WITH_THREAD
3097 /* Tear down the thread & interpreter states.
3098 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003099 * call the thread clear & delete functions, and indeed insist on
3100 * doing that themselves. The lock must be held during the clear, but
3101 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003102 */
3103 PyInterpreterState_Clear(pInterpreterState);
3104 PyEval_ReleaseThread(pThreadState);
3105 PyInterpreterState_Delete(pInterpreterState);
3106#endif
3107
Fredrik Lundh56055a42000-07-23 19:47:12 +00003108 return result;
3109}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003110
3111#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003113posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003114{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003115 char *name;
3116 char *mode = "r";
3117 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003118 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003119 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003120 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003121 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003122 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003123 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003124 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003125 if (fp == NULL)
3126 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003127 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003128 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003129 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003130 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003131}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003132#endif
3133
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003134#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003135
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003136
Guido van Rossumb6775db1994-08-01 11:34:53 +00003137#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003138static char posix_setuid__doc__[] =
3139"setuid(uid) -> None\n\
3140Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003142posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003143{
3144 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003145 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003146 return NULL;
3147 if (setuid(uid) < 0)
3148 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003149 Py_INCREF(Py_None);
3150 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003151}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003152#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003154
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003155#ifdef HAVE_SETEUID
3156static char posix_seteuid__doc__[] =
3157"seteuid(uid) -> None\n\
3158Set the current process's effective user id.";
3159static PyObject *
3160posix_seteuid (PyObject *self, PyObject *args)
3161{
3162 int euid;
3163 if (!PyArg_ParseTuple(args, "i", &euid)) {
3164 return NULL;
3165 } else if (seteuid(euid) < 0) {
3166 return posix_error();
3167 } else {
3168 Py_INCREF(Py_None);
3169 return Py_None;
3170 }
3171}
3172#endif /* HAVE_SETEUID */
3173
3174#ifdef HAVE_SETEGID
3175static char posix_setegid__doc__[] =
3176"setegid(gid) -> None\n\
3177Set the current process's effective group id.";
3178static PyObject *
3179posix_setegid (PyObject *self, PyObject *args)
3180{
3181 int egid;
3182 if (!PyArg_ParseTuple(args, "i", &egid)) {
3183 return NULL;
3184 } else if (setegid(egid) < 0) {
3185 return posix_error();
3186 } else {
3187 Py_INCREF(Py_None);
3188 return Py_None;
3189 }
3190}
3191#endif /* HAVE_SETEGID */
3192
3193#ifdef HAVE_SETREUID
3194static char posix_setreuid__doc__[] =
3195"seteuid(ruid, euid) -> None\n\
3196Set the current process's real and effective user ids.";
3197static PyObject *
3198posix_setreuid (PyObject *self, PyObject *args)
3199{
3200 int ruid, euid;
3201 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3202 return NULL;
3203 } else if (setreuid(ruid, euid) < 0) {
3204 return posix_error();
3205 } else {
3206 Py_INCREF(Py_None);
3207 return Py_None;
3208 }
3209}
3210#endif /* HAVE_SETREUID */
3211
3212#ifdef HAVE_SETREGID
3213static char posix_setregid__doc__[] =
3214"setegid(rgid, egid) -> None\n\
3215Set the current process's real and effective group ids.";
3216static PyObject *
3217posix_setregid (PyObject *self, PyObject *args)
3218{
3219 int rgid, egid;
3220 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3221 return NULL;
3222 } else if (setregid(rgid, egid) < 0) {
3223 return posix_error();
3224 } else {
3225 Py_INCREF(Py_None);
3226 return Py_None;
3227 }
3228}
3229#endif /* HAVE_SETREGID */
3230
Guido van Rossumb6775db1994-08-01 11:34:53 +00003231#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003232static char posix_setgid__doc__[] =
3233"setgid(gid) -> None\n\
3234Set the current process's group id.";
3235
Barry Warsaw53699e91996-12-10 23:23:01 +00003236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003237posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003238{
3239 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003240 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003241 return NULL;
3242 if (setgid(gid) < 0)
3243 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003244 Py_INCREF(Py_None);
3245 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003246}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003247#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003248
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003249#ifdef HAVE_SETGROUPS
3250static char posix_setgroups__doc__[] =
3251"setgroups(list) -> None\n\
3252Set the groups of the current process to list.";
3253
3254static PyObject *
3255posix_setgroups(PyObject *self, PyObject *args)
3256{
3257 PyObject *groups;
3258 int i, len;
3259 gid_t grouplist[MAX_GROUPS];
3260
3261 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3262 return NULL;
3263 if (!PySequence_Check(groups)) {
3264 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3265 return NULL;
3266 }
3267 len = PySequence_Size(groups);
3268 if (len > MAX_GROUPS) {
3269 PyErr_SetString(PyExc_ValueError, "too many groups");
3270 return NULL;
3271 }
3272 for(i = 0; i < len; i++) {
3273 PyObject *elem;
3274 elem = PySequence_GetItem(groups, i);
3275 if (!elem)
3276 return NULL;
3277 if (!PyInt_Check(elem)) {
3278 PyErr_SetString(PyExc_TypeError,
3279 "groups must be integers");
3280 Py_DECREF(elem);
3281 return NULL;
3282 }
3283 /* XXX: check that value fits into gid_t. */
3284 grouplist[i] = PyInt_AsLong(elem);
3285 Py_DECREF(elem);
3286 }
3287
3288 if (setgroups(len, grouplist) < 0)
3289 return posix_error();
3290 Py_INCREF(Py_None);
3291 return Py_None;
3292}
3293#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003294
Guido van Rossumb6775db1994-08-01 11:34:53 +00003295#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003296static char posix_waitpid__doc__[] =
3297"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003298Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003299
Barry Warsaw53699e91996-12-10 23:23:01 +00003300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003301posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003302{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003303 int pid, options;
3304#ifdef UNION_WAIT
3305 union wait status;
3306#define status_i (status.w_status)
3307#else
3308 int status;
3309#define status_i status
3310#endif
3311 status_i = 0;
3312
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003313 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003314 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003315 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003316#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003317 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003318#else
3319 pid = waitpid(pid, &status, options);
3320#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003321 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003322 if (pid == -1)
3323 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003324 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003325 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003326}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003327#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003329
Guido van Rossumad0ee831995-03-01 10:34:45 +00003330#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003331static char posix_wait__doc__[] =
3332"wait() -> (pid, status)\n\
3333Wait for completion of a child process.";
3334
Barry Warsaw53699e91996-12-10 23:23:01 +00003335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003336posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003337{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003338 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003339#ifdef UNION_WAIT
3340 union wait status;
3341#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003342#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003343 int status;
3344#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003345#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003346 if (!PyArg_ParseTuple(args, ":wait"))
3347 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003348 status_i = 0;
3349 Py_BEGIN_ALLOW_THREADS
3350 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003351 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003352 if (pid == -1)
3353 return posix_error();
3354 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003355 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003356#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003357}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003358#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003359
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003360
3361static char posix_lstat__doc__[] =
3362"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3363Like stat(path), but do not follow symbolic links.";
3364
Barry Warsaw53699e91996-12-10 23:23:01 +00003365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003366posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003367{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003368#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003369 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003370#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003371 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003372#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003373}
3374
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003375
Guido van Rossumb6775db1994-08-01 11:34:53 +00003376#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003377static char posix_readlink__doc__[] =
3378"readlink(path) -> path\n\
3379Return a string representing the path to which the symbolic link points.";
3380
Barry Warsaw53699e91996-12-10 23:23:01 +00003381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003382posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003383{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003384 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003385 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003386 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003387 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003388 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003389 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003390 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003391 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003392 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003393 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003394 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003395}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003396#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003397
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003398
Guido van Rossumb6775db1994-08-01 11:34:53 +00003399#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003400static char posix_symlink__doc__[] =
3401"symlink(src, dst) -> None\n\
3402Create a symbolic link.";
3403
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003404static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003405posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003406{
Mark Hammondef8b6542001-05-13 08:04:26 +00003407 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003408}
3409#endif /* HAVE_SYMLINK */
3410
3411
3412#ifdef HAVE_TIMES
3413#ifndef HZ
3414#define HZ 60 /* Universal constant :-) */
3415#endif /* HZ */
3416
Guido van Rossumd48f2521997-12-05 22:19:34 +00003417#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3418static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003419system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003420{
3421 ULONG value = 0;
3422
3423 Py_BEGIN_ALLOW_THREADS
3424 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3425 Py_END_ALLOW_THREADS
3426
3427 return value;
3428}
3429
3430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003431posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003432{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003433 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003434 return NULL;
3435
3436 /* Currently Only Uptime is Provided -- Others Later */
3437 return Py_BuildValue("ddddd",
3438 (double)0 /* t.tms_utime / HZ */,
3439 (double)0 /* t.tms_stime / HZ */,
3440 (double)0 /* t.tms_cutime / HZ */,
3441 (double)0 /* t.tms_cstime / HZ */,
3442 (double)system_uptime() / 1000);
3443}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003444#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003446posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003447{
3448 struct tms t;
3449 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003450 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003451 return NULL;
3452 errno = 0;
3453 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003454 if (c == (clock_t) -1)
3455 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003456 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003457 (double)t.tms_utime / HZ,
3458 (double)t.tms_stime / HZ,
3459 (double)t.tms_cutime / HZ,
3460 (double)t.tms_cstime / HZ,
3461 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003462}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003463#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003464#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003465
3466
Guido van Rossum87755a21996-09-07 00:59:43 +00003467#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003468#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003469static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003470posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003471{
3472 FILETIME create, exit, kernel, user;
3473 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003474 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003475 return NULL;
3476 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003477 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3478 /* The fields of a FILETIME structure are the hi and lo part
3479 of a 64-bit value expressed in 100 nanosecond units.
3480 1e7 is one second in such units; 1e-7 the inverse.
3481 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3482 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003483 return Py_BuildValue(
3484 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003485 (double)(kernel.dwHighDateTime*429.4967296 +
3486 kernel.dwLowDateTime*1e-7),
3487 (double)(user.dwHighDateTime*429.4967296 +
3488 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003489 (double)0,
3490 (double)0,
3491 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003492}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003493#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003494
3495#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003496static char posix_times__doc__[] =
3497"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3498Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003499#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003501
Guido van Rossumb6775db1994-08-01 11:34:53 +00003502#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003503static char posix_setsid__doc__[] =
3504"setsid() -> None\n\
3505Call the system call setsid().";
3506
Barry Warsaw53699e91996-12-10 23:23:01 +00003507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003508posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003509{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003510 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003511 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003512 if (setsid() < 0)
3513 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003514 Py_INCREF(Py_None);
3515 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003516}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003517#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003518
Guido van Rossumb6775db1994-08-01 11:34:53 +00003519#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003520static char posix_setpgid__doc__[] =
3521"setpgid(pid, pgrp) -> None\n\
3522Call the system call setpgid().";
3523
Barry Warsaw53699e91996-12-10 23:23:01 +00003524static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003525posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003526{
3527 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003528 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003529 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003530 if (setpgid(pid, pgrp) < 0)
3531 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003532 Py_INCREF(Py_None);
3533 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003534}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003535#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003537
Guido van Rossumb6775db1994-08-01 11:34:53 +00003538#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003539static char posix_tcgetpgrp__doc__[] =
3540"tcgetpgrp(fd) -> pgid\n\
3541Return the process group associated with the terminal given by a fd.";
3542
Barry Warsaw53699e91996-12-10 23:23:01 +00003543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003544posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003545{
3546 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003547 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003548 return NULL;
3549 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003550 if (pgid < 0)
3551 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003552 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003553}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003554#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003555
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003556
Guido van Rossumb6775db1994-08-01 11:34:53 +00003557#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003558static char posix_tcsetpgrp__doc__[] =
3559"tcsetpgrp(fd, pgid) -> None\n\
3560Set the process group associated with the terminal given by a fd.";
3561
Barry Warsaw53699e91996-12-10 23:23:01 +00003562static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003563posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003564{
3565 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003566 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003567 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003568 if (tcsetpgrp(fd, pgid) < 0)
3569 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003570 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003571 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003572}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003573#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003574
Guido van Rossum687dd131993-05-17 08:34:16 +00003575/* Functions acting on file descriptors */
3576
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003577static char posix_open__doc__[] =
3578"open(filename, flag [, mode=0777]) -> fd\n\
3579Open a file (for low level IO).";
3580
Barry Warsaw53699e91996-12-10 23:23:01 +00003581static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003582posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003583{
Mark Hammondef8b6542001-05-13 08:04:26 +00003584 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003585 int flag;
3586 int mode = 0777;
3587 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003588 if (!PyArg_ParseTuple(args, "eti|i",
3589 Py_FileSystemDefaultEncoding, &file,
3590 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003591 return NULL;
3592
Barry Warsaw53699e91996-12-10 23:23:01 +00003593 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003594 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003595 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003596 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003597 return posix_error_with_allocated_filename(file);
3598 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003599 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003600}
3601
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003602
3603static char posix_close__doc__[] =
3604"close(fd) -> None\n\
3605Close a file descriptor (for low level IO).";
3606
Barry Warsaw53699e91996-12-10 23:23:01 +00003607static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003608posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003609{
3610 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003611 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003612 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003613 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003614 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003615 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003616 if (res < 0)
3617 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003618 Py_INCREF(Py_None);
3619 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003620}
3621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003622
3623static char posix_dup__doc__[] =
3624"dup(fd) -> fd2\n\
3625Return a duplicate of a file descriptor.";
3626
Barry Warsaw53699e91996-12-10 23:23:01 +00003627static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003628posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003629{
3630 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003631 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003632 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003633 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003634 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003635 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003636 if (fd < 0)
3637 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003638 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003639}
3640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003641
3642static char posix_dup2__doc__[] =
3643"dup2(fd, fd2) -> None\n\
3644Duplicate file descriptor.";
3645
Barry Warsaw53699e91996-12-10 23:23:01 +00003646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003647posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003648{
3649 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003650 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003651 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003652 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003653 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003654 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003655 if (res < 0)
3656 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003657 Py_INCREF(Py_None);
3658 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003659}
3660
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003661
3662static char posix_lseek__doc__[] =
3663"lseek(fd, pos, how) -> newpos\n\
3664Set the current position of a file descriptor.";
3665
Barry Warsaw53699e91996-12-10 23:23:01 +00003666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003667posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003668{
3669 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003670#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003671 LONG_LONG pos, res;
3672#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003673 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003674#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003675 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003676 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003677 return NULL;
3678#ifdef SEEK_SET
3679 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3680 switch (how) {
3681 case 0: how = SEEK_SET; break;
3682 case 1: how = SEEK_CUR; break;
3683 case 2: how = SEEK_END; break;
3684 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003685#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003686
3687#if !defined(HAVE_LARGEFILE_SUPPORT)
3688 pos = PyInt_AsLong(posobj);
3689#else
3690 pos = PyLong_Check(posobj) ?
3691 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3692#endif
3693 if (PyErr_Occurred())
3694 return NULL;
3695
Barry Warsaw53699e91996-12-10 23:23:01 +00003696 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003697#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003698 res = _lseeki64(fd, pos, how);
3699#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003700 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003701#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003702 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003703 if (res < 0)
3704 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003705
3706#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003707 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003708#else
3709 return PyLong_FromLongLong(res);
3710#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003711}
3712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003713
3714static char posix_read__doc__[] =
3715"read(fd, buffersize) -> string\n\
3716Read a file descriptor.";
3717
Barry Warsaw53699e91996-12-10 23:23:01 +00003718static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003719posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003720{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003721 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003722 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003723 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003724 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003725 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003726 if (buffer == NULL)
3727 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003728 Py_BEGIN_ALLOW_THREADS
3729 n = read(fd, PyString_AsString(buffer), size);
3730 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003731 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003732 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003733 return posix_error();
3734 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003735 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003736 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003737 return buffer;
3738}
3739
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003740
3741static char posix_write__doc__[] =
3742"write(fd, string) -> byteswritten\n\
3743Write a string to a file descriptor.";
3744
Barry Warsaw53699e91996-12-10 23:23:01 +00003745static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003746posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003747{
3748 int fd, size;
3749 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003750 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003751 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003752 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003753 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003754 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003755 if (size < 0)
3756 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003757 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003758}
3759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003760
3761static char posix_fstat__doc__[]=
3762"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3763Like stat(), but for an open file descriptor.";
3764
Barry Warsaw53699e91996-12-10 23:23:01 +00003765static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003766posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003767{
3768 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003769 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003770 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003771 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003772 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003773 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003774 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003775 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003776 if (res != 0)
3777 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003778
3779 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003780}
3781
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003782
3783static char posix_fdopen__doc__[] =
3784"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3785Return an open file object connected to a file descriptor.";
3786
Barry Warsaw53699e91996-12-10 23:23:01 +00003787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003788posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003789{
Guido van Rossum687dd131993-05-17 08:34:16 +00003790 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003791 char *mode = "r";
3792 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003793 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003794 PyObject *f;
3795 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003796 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003797
Barry Warsaw53699e91996-12-10 23:23:01 +00003798 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003799 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003800 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003801 if (fp == NULL)
3802 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003803 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003804 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003805 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003806 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003807}
3808
Skip Montanaro1517d842000-07-19 14:34:14 +00003809static char posix_isatty__doc__[] =
3810"isatty(fd) -> Boolean\n\
3811Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003812connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003813
3814static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003815posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003816{
3817 int fd;
3818 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3819 return NULL;
3820 return Py_BuildValue("i", isatty(fd));
3821}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003822
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003823#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003824static char posix_pipe__doc__[] =
3825"pipe() -> (read_end, write_end)\n\
3826Create a pipe.";
3827
Barry Warsaw53699e91996-12-10 23:23:01 +00003828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003829posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003830{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003831#if defined(PYOS_OS2)
3832 HFILE read, write;
3833 APIRET rc;
3834
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003835 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003836 return NULL;
3837
3838 Py_BEGIN_ALLOW_THREADS
3839 rc = DosCreatePipe( &read, &write, 4096);
3840 Py_END_ALLOW_THREADS
3841 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003842 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003843
3844 return Py_BuildValue("(ii)", read, write);
3845#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003846#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003847 int fds[2];
3848 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003849 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003850 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003851 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003852 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003853 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003854 if (res != 0)
3855 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003856 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003857#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003858 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003859 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003860 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003861 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003862 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003863 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003864 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003865 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003866 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003867 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003868 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3869 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003870 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003871#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003872#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003873}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003874#endif /* HAVE_PIPE */
3875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003876
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003877#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003878static char posix_mkfifo__doc__[] =
3879"mkfifo(file, [, mode=0666]) -> None\n\
3880Create a FIFO (a POSIX named pipe).";
3881
Barry Warsaw53699e91996-12-10 23:23:01 +00003882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003883posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003884{
3885 char *file;
3886 int mode = 0666;
3887 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003888 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003889 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003890 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003891 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003892 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003893 if (res < 0)
3894 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003895 Py_INCREF(Py_None);
3896 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003897}
3898#endif
3899
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003900
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003901#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003902static char posix_ftruncate__doc__[] =
3903"ftruncate(fd, length) -> None\n\
3904Truncate a file to a specified length.";
3905
Barry Warsaw53699e91996-12-10 23:23:01 +00003906static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003907posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003908{
3909 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003910 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003911 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003912 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003913
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003914 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003915 return NULL;
3916
3917#if !defined(HAVE_LARGEFILE_SUPPORT)
3918 length = PyInt_AsLong(lenobj);
3919#else
3920 length = PyLong_Check(lenobj) ?
3921 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3922#endif
3923 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003924 return NULL;
3925
Barry Warsaw53699e91996-12-10 23:23:01 +00003926 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003927 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003928 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003929 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003930 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003931 return NULL;
3932 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003933 Py_INCREF(Py_None);
3934 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003935}
3936#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003937
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003938#ifdef NeXT
3939#define HAVE_PUTENV
3940/* Steve Spicklemire got this putenv from NeXTAnswers */
3941static int
3942putenv(char *newval)
3943{
3944 extern char **environ;
3945
3946 static int firstTime = 1;
3947 char **ep;
3948 char *cp;
3949 int esiz;
3950 char *np;
3951
3952 if (!(np = strchr(newval, '=')))
3953 return 1;
3954 *np = '\0';
3955
3956 /* look it up */
3957 for (ep=environ ; *ep ; ep++)
3958 {
3959 /* this should always be true... */
3960 if (cp = strchr(*ep, '='))
3961 {
3962 *cp = '\0';
3963 if (!strcmp(*ep, newval))
3964 {
3965 /* got it! */
3966 *cp = '=';
3967 break;
3968 }
3969 *cp = '=';
3970 }
3971 else
3972 {
3973 *np = '=';
3974 return 1;
3975 }
3976 }
3977
3978 *np = '=';
3979 if (*ep)
3980 {
3981 /* the string was already there:
3982 just replace it with the new one */
3983 *ep = newval;
3984 return 0;
3985 }
3986
3987 /* expand environ by one */
3988 for (esiz=2, ep=environ ; *ep ; ep++)
3989 esiz++;
3990 if (firstTime)
3991 {
3992 char **epp;
3993 char **newenv;
3994 if (!(newenv = malloc(esiz * sizeof(char *))))
3995 return 1;
3996
3997 for (ep=environ, epp=newenv ; *ep ;)
3998 *epp++ = *ep++;
3999 *epp++ = newval;
4000 *epp = (char *) 0;
4001 environ = newenv;
4002 }
4003 else
4004 {
4005 if (!(environ = realloc(environ, esiz * sizeof(char *))))
4006 return 1;
4007 environ[esiz - 2] = newval;
4008 environ[esiz - 1] = (char *) 0;
4009 firstTime = 0;
4010 }
4011
4012 return 0;
4013}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00004014#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004015
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004016
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004017#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004018static char posix_putenv__doc__[] =
4019"putenv(key, value) -> None\n\
4020Change or add an environment variable.";
4021
Fred Drake762e2061999-08-26 17:23:54 +00004022/* Save putenv() parameters as values here, so we can collect them when they
4023 * get re-set with another call for the same key. */
4024static PyObject *posix_putenv_garbage;
4025
Barry Warsaw53699e91996-12-10 23:23:01 +00004026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004027posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004028{
4029 char *s1, *s2;
4030 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004031 PyObject *newstr;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004032
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004033 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004034 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004035
4036#if defined(PYOS_OS2)
4037 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4038 APIRET rc;
4039
4040 if (strlen(s2) == 0) /* If New Value is an Empty String */
4041 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4042
4043 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4044 if (rc != NO_ERROR)
4045 return os2_error(rc);
4046
4047 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4048 APIRET rc;
4049
4050 if (strlen(s2) == 0) /* If New Value is an Empty String */
4051 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4052
4053 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4054 if (rc != NO_ERROR)
4055 return os2_error(rc);
4056 } else {
4057#endif
4058
Fred Drake762e2061999-08-26 17:23:54 +00004059 /* XXX This can leak memory -- not easy to fix :-( */
4060 newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
4061 if (newstr == NULL)
4062 return PyErr_NoMemory();
4063 new = PyString_AS_STRING(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004064 (void) sprintf(new, "%s=%s", s1, s2);
4065 if (putenv(new)) {
4066 posix_error();
4067 return NULL;
4068 }
Fred Drake762e2061999-08-26 17:23:54 +00004069 /* Install the first arg and newstr in posix_putenv_garbage;
4070 * this will cause previous value to be collected. This has to
4071 * happen after the real putenv() call because the old value
4072 * was still accessible until then. */
4073 if (PyDict_SetItem(posix_putenv_garbage,
4074 PyTuple_GET_ITEM(args, 0), newstr)) {
4075 /* really not much we can do; just leak */
4076 PyErr_Clear();
4077 }
4078 else {
4079 Py_DECREF(newstr);
4080 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004081
4082#if defined(PYOS_OS2)
4083 }
4084#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004085 Py_INCREF(Py_None);
4086 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004087}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004088#endif /* putenv */
4089
Guido van Rossumc524d952001-10-19 01:31:59 +00004090#ifdef HAVE_UNSETENV
4091static char posix_unsetenv__doc__[] =
4092"unsetenv(key) -> None\n\
4093Delete an environment variable.";
4094
4095static PyObject *
4096posix_unsetenv(PyObject *self, PyObject *args)
4097{
4098 char *s1;
4099
4100 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4101 return NULL;
4102
4103 unsetenv(s1);
4104
4105 /* Remove the key from posix_putenv_garbage;
4106 * this will cause it to be collected. This has to
4107 * happen after the real unsetenv() call because the
4108 * old value was still accessible until then.
4109 */
4110 if (PyDict_DelItem(posix_putenv_garbage,
4111 PyTuple_GET_ITEM(args, 0))) {
4112 /* really not much we can do; just leak */
4113 PyErr_Clear();
4114 }
4115
4116 Py_INCREF(Py_None);
4117 return Py_None;
4118}
4119#endif /* unsetenv */
4120
Guido van Rossumb6a47161997-09-15 22:54:34 +00004121#ifdef HAVE_STRERROR
4122static char posix_strerror__doc__[] =
4123"strerror(code) -> string\n\
4124Translate an error code to a message string.";
4125
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004126static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004127posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004128{
4129 int code;
4130 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004131 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004132 return NULL;
4133 message = strerror(code);
4134 if (message == NULL) {
4135 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004136 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004137 return NULL;
4138 }
4139 return PyString_FromString(message);
4140}
4141#endif /* strerror */
4142
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004143
Guido van Rossumc9641791998-08-04 15:26:23 +00004144#ifdef HAVE_SYS_WAIT_H
4145
4146#ifdef WIFSTOPPED
4147static char posix_WIFSTOPPED__doc__[] =
4148"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004149Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004150
4151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004152posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004153{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004154#ifdef UNION_WAIT
4155 union wait status;
4156#define status_i (status.w_status)
4157#else
4158 int status;
4159#define status_i status
4160#endif
4161 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004162
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004163 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004164 {
4165 return NULL;
4166 }
4167
4168 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004169#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004170}
4171#endif /* WIFSTOPPED */
4172
4173#ifdef WIFSIGNALED
4174static char posix_WIFSIGNALED__doc__[] =
4175"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004176Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004177
4178static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004179posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004180{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004181#ifdef UNION_WAIT
4182 union wait status;
4183#define status_i (status.w_status)
4184#else
4185 int status;
4186#define status_i status
4187#endif
4188 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004189
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004190 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004191 {
4192 return NULL;
4193 }
4194
4195 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004196#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004197}
4198#endif /* WIFSIGNALED */
4199
4200#ifdef WIFEXITED
4201static char posix_WIFEXITED__doc__[] =
4202"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004203Return true if the process returning 'status' exited using the exit()\n\
4204system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004205
4206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004207posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004208{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004209#ifdef UNION_WAIT
4210 union wait status;
4211#define status_i (status.w_status)
4212#else
4213 int status;
4214#define status_i status
4215#endif
4216 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004217
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004218 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004219 {
4220 return NULL;
4221 }
4222
4223 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004224#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004225}
4226#endif /* WIFEXITED */
4227
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004228#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004229static char posix_WEXITSTATUS__doc__[] =
4230"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004231Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004232
4233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004234posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004235{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004236#ifdef UNION_WAIT
4237 union wait status;
4238#define status_i (status.w_status)
4239#else
4240 int status;
4241#define status_i status
4242#endif
4243 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004244
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004245 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004246 {
4247 return NULL;
4248 }
4249
4250 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004251#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004252}
4253#endif /* WEXITSTATUS */
4254
4255#ifdef WTERMSIG
4256static char posix_WTERMSIG__doc__[] =
4257"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004258Return the signal that terminated the process that provided the 'status'\n\
4259value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004260
4261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004262posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004263{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004264#ifdef UNION_WAIT
4265 union wait status;
4266#define status_i (status.w_status)
4267#else
4268 int status;
4269#define status_i status
4270#endif
4271 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004272
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004273 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004274 {
4275 return NULL;
4276 }
4277
4278 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004279#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004280}
4281#endif /* WTERMSIG */
4282
4283#ifdef WSTOPSIG
4284static char posix_WSTOPSIG__doc__[] =
4285"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004286Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004287
4288static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004289posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004290{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004291#ifdef UNION_WAIT
4292 union wait status;
4293#define status_i (status.w_status)
4294#else
4295 int status;
4296#define status_i status
4297#endif
4298 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004299
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004300 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004301 {
4302 return NULL;
4303 }
4304
4305 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004306#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004307}
4308#endif /* WSTOPSIG */
4309
4310#endif /* HAVE_SYS_WAIT_H */
4311
4312
Guido van Rossum94f6f721999-01-06 18:42:14 +00004313#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004314#ifdef _SCO_DS
4315/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4316 needed definitions in sys/statvfs.h */
4317#define _SVID3
4318#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004319#include <sys/statvfs.h>
4320
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004321static PyObject*
4322_pystatvfs_fromstructstatvfs(struct statvfs st) {
4323 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4324 if (v == NULL)
4325 return NULL;
4326
4327#if !defined(HAVE_LARGEFILE_SUPPORT)
4328 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4329 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4330 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4331 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4332 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4333 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4334 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4335 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4336 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4337 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4338#else
4339 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4340 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4341 PyStructSequence_SET_ITEM(v, 2,
4342 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
4343 PyStructSequence_SET_ITEM(v, 3,
4344 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4345 PyStructSequence_SET_ITEM(v, 4,
4346 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
4347 PyStructSequence_SET_ITEM(v, 5,
4348 PyLong_FromLongLong((LONG_LONG) st.f_files));
4349 PyStructSequence_SET_ITEM(v, 6,
4350 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
4351 PyStructSequence_SET_ITEM(v, 7,
4352 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4353 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4354 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4355#endif
4356
4357 return v;
4358}
4359
Guido van Rossum94f6f721999-01-06 18:42:14 +00004360static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004361"fstatvfs(fd) -> \n\
4362 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004363Perform an fstatvfs system call on the given fd.";
4364
4365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004366posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004367{
4368 int fd, res;
4369 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004370
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004371 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004372 return NULL;
4373 Py_BEGIN_ALLOW_THREADS
4374 res = fstatvfs(fd, &st);
4375 Py_END_ALLOW_THREADS
4376 if (res != 0)
4377 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004378
4379 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004380}
4381#endif /* HAVE_FSTATVFS */
4382
4383
4384#if defined(HAVE_STATVFS)
4385#include <sys/statvfs.h>
4386
4387static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004388"statvfs(path) -> \n\
4389 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004390Perform a statvfs system call on the given path.";
4391
4392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004393posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004394{
4395 char *path;
4396 int res;
4397 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004398 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004399 return NULL;
4400 Py_BEGIN_ALLOW_THREADS
4401 res = statvfs(path, &st);
4402 Py_END_ALLOW_THREADS
4403 if (res != 0)
4404 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004405
4406 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004407}
4408#endif /* HAVE_STATVFS */
4409
4410
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004411#ifdef HAVE_TEMPNAM
4412static char posix_tempnam__doc__[] = "\
4413tempnam([dir[, prefix]]) -> string\n\
4414Return a unique name for a temporary file.\n\
4415The directory and a short may be specified as strings; they may be omitted\n\
4416or None if not needed.";
4417
4418static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004419posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004420{
4421 PyObject *result = NULL;
4422 char *dir = NULL;
4423 char *pfx = NULL;
4424 char *name;
4425
4426 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4427 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004428
4429 if (PyErr_Warn(PyExc_RuntimeWarning,
4430 "tempnam is a potential security risk to your program") < 0)
4431 return NULL;
4432
Fred Drake78b71c22001-07-17 20:37:36 +00004433#ifdef MS_WIN32
4434 name = _tempnam(dir, pfx);
4435#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004436 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004437#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004438 if (name == NULL)
4439 return PyErr_NoMemory();
4440 result = PyString_FromString(name);
4441 free(name);
4442 return result;
4443}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004444#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004445
4446
4447#ifdef HAVE_TMPFILE
4448static char posix_tmpfile__doc__[] = "\
4449tmpfile() -> file object\n\
4450Create a temporary file with no directory entries.";
4451
4452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004453posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004454{
4455 FILE *fp;
4456
4457 if (!PyArg_ParseTuple(args, ":tmpfile"))
4458 return NULL;
4459 fp = tmpfile();
4460 if (fp == NULL)
4461 return posix_error();
4462 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4463}
4464#endif
4465
4466
4467#ifdef HAVE_TMPNAM
4468static char posix_tmpnam__doc__[] = "\
4469tmpnam() -> string\n\
4470Return a unique name for a temporary file.";
4471
4472static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004473posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004474{
4475 char buffer[L_tmpnam];
4476 char *name;
4477
4478 if (!PyArg_ParseTuple(args, ":tmpnam"))
4479 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004480
4481 if (PyErr_Warn(PyExc_RuntimeWarning,
4482 "tmpnam is a potential security risk to your program") < 0)
4483 return NULL;
4484
Greg Wardb48bc172000-03-01 21:51:56 +00004485#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004486 name = tmpnam_r(buffer);
4487#else
4488 name = tmpnam(buffer);
4489#endif
4490 if (name == NULL) {
4491 PyErr_SetObject(PyExc_OSError,
4492 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004493#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004494 "unexpected NULL from tmpnam_r"
4495#else
4496 "unexpected NULL from tmpnam"
4497#endif
4498 ));
4499 return NULL;
4500 }
4501 return PyString_FromString(buffer);
4502}
4503#endif
4504
4505
Fred Drakec9680921999-12-13 16:37:25 +00004506/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4507 * It maps strings representing configuration variable names to
4508 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004509 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004510 * rarely-used constants. There are three separate tables that use
4511 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004512 *
4513 * This code is always included, even if none of the interfaces that
4514 * need it are included. The #if hackery needed to avoid it would be
4515 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004516 */
4517struct constdef {
4518 char *name;
4519 long value;
4520};
4521
Fred Drake12c6e2d1999-12-14 21:25:03 +00004522static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004523conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4524 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004525{
4526 if (PyInt_Check(arg)) {
4527 *valuep = PyInt_AS_LONG(arg);
4528 return 1;
4529 }
4530 if (PyString_Check(arg)) {
4531 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004532 size_t lo = 0;
4533 size_t mid;
4534 size_t hi = tablesize;
4535 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004536 char *confname = PyString_AS_STRING(arg);
4537 while (lo < hi) {
4538 mid = (lo + hi) / 2;
4539 cmp = strcmp(confname, table[mid].name);
4540 if (cmp < 0)
4541 hi = mid;
4542 else if (cmp > 0)
4543 lo = mid + 1;
4544 else {
4545 *valuep = table[mid].value;
4546 return 1;
4547 }
4548 }
4549 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4550 }
4551 else
4552 PyErr_SetString(PyExc_TypeError,
4553 "configuration names must be strings or integers");
4554 return 0;
4555}
4556
4557
4558#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4559static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004560#ifdef _PC_ABI_AIO_XFER_MAX
4561 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4562#endif
4563#ifdef _PC_ABI_ASYNC_IO
4564 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4565#endif
Fred Drakec9680921999-12-13 16:37:25 +00004566#ifdef _PC_ASYNC_IO
4567 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4568#endif
4569#ifdef _PC_CHOWN_RESTRICTED
4570 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4571#endif
4572#ifdef _PC_FILESIZEBITS
4573 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4574#endif
4575#ifdef _PC_LAST
4576 {"PC_LAST", _PC_LAST},
4577#endif
4578#ifdef _PC_LINK_MAX
4579 {"PC_LINK_MAX", _PC_LINK_MAX},
4580#endif
4581#ifdef _PC_MAX_CANON
4582 {"PC_MAX_CANON", _PC_MAX_CANON},
4583#endif
4584#ifdef _PC_MAX_INPUT
4585 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4586#endif
4587#ifdef _PC_NAME_MAX
4588 {"PC_NAME_MAX", _PC_NAME_MAX},
4589#endif
4590#ifdef _PC_NO_TRUNC
4591 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4592#endif
4593#ifdef _PC_PATH_MAX
4594 {"PC_PATH_MAX", _PC_PATH_MAX},
4595#endif
4596#ifdef _PC_PIPE_BUF
4597 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4598#endif
4599#ifdef _PC_PRIO_IO
4600 {"PC_PRIO_IO", _PC_PRIO_IO},
4601#endif
4602#ifdef _PC_SOCK_MAXBUF
4603 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4604#endif
4605#ifdef _PC_SYNC_IO
4606 {"PC_SYNC_IO", _PC_SYNC_IO},
4607#endif
4608#ifdef _PC_VDISABLE
4609 {"PC_VDISABLE", _PC_VDISABLE},
4610#endif
4611};
4612
Fred Drakec9680921999-12-13 16:37:25 +00004613static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004614conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004615{
4616 return conv_confname(arg, valuep, posix_constants_pathconf,
4617 sizeof(posix_constants_pathconf)
4618 / sizeof(struct constdef));
4619}
4620#endif
4621
4622#ifdef HAVE_FPATHCONF
4623static char posix_fpathconf__doc__[] = "\
4624fpathconf(fd, name) -> integer\n\
4625Return the configuration limit name for the file descriptor fd.\n\
4626If there is no limit, return -1.";
4627
4628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004629posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004630{
4631 PyObject *result = NULL;
4632 int name, fd;
4633
Fred Drake12c6e2d1999-12-14 21:25:03 +00004634 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4635 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004636 long limit;
4637
4638 errno = 0;
4639 limit = fpathconf(fd, name);
4640 if (limit == -1 && errno != 0)
4641 posix_error();
4642 else
4643 result = PyInt_FromLong(limit);
4644 }
4645 return result;
4646}
4647#endif
4648
4649
4650#ifdef HAVE_PATHCONF
4651static char posix_pathconf__doc__[] = "\
4652pathconf(path, name) -> integer\n\
4653Return the configuration limit name for the file or directory path.\n\
4654If there is no limit, return -1.";
4655
4656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004657posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004658{
4659 PyObject *result = NULL;
4660 int name;
4661 char *path;
4662
4663 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4664 conv_path_confname, &name)) {
4665 long limit;
4666
4667 errno = 0;
4668 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004669 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004670 if (errno == EINVAL)
4671 /* could be a path or name problem */
4672 posix_error();
4673 else
4674 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004675 }
Fred Drakec9680921999-12-13 16:37:25 +00004676 else
4677 result = PyInt_FromLong(limit);
4678 }
4679 return result;
4680}
4681#endif
4682
4683#ifdef HAVE_CONFSTR
4684static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004685#ifdef _CS_ARCHITECTURE
4686 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4687#endif
4688#ifdef _CS_HOSTNAME
4689 {"CS_HOSTNAME", _CS_HOSTNAME},
4690#endif
4691#ifdef _CS_HW_PROVIDER
4692 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4693#endif
4694#ifdef _CS_HW_SERIAL
4695 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4696#endif
4697#ifdef _CS_INITTAB_NAME
4698 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4699#endif
Fred Drakec9680921999-12-13 16:37:25 +00004700#ifdef _CS_LFS64_CFLAGS
4701 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4702#endif
4703#ifdef _CS_LFS64_LDFLAGS
4704 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4705#endif
4706#ifdef _CS_LFS64_LIBS
4707 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4708#endif
4709#ifdef _CS_LFS64_LINTFLAGS
4710 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4711#endif
4712#ifdef _CS_LFS_CFLAGS
4713 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4714#endif
4715#ifdef _CS_LFS_LDFLAGS
4716 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4717#endif
4718#ifdef _CS_LFS_LIBS
4719 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4720#endif
4721#ifdef _CS_LFS_LINTFLAGS
4722 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4723#endif
Fred Draked86ed291999-12-15 15:34:33 +00004724#ifdef _CS_MACHINE
4725 {"CS_MACHINE", _CS_MACHINE},
4726#endif
Fred Drakec9680921999-12-13 16:37:25 +00004727#ifdef _CS_PATH
4728 {"CS_PATH", _CS_PATH},
4729#endif
Fred Draked86ed291999-12-15 15:34:33 +00004730#ifdef _CS_RELEASE
4731 {"CS_RELEASE", _CS_RELEASE},
4732#endif
4733#ifdef _CS_SRPC_DOMAIN
4734 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4735#endif
4736#ifdef _CS_SYSNAME
4737 {"CS_SYSNAME", _CS_SYSNAME},
4738#endif
4739#ifdef _CS_VERSION
4740 {"CS_VERSION", _CS_VERSION},
4741#endif
Fred Drakec9680921999-12-13 16:37:25 +00004742#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4743 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4744#endif
4745#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4746 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4747#endif
4748#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4749 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4750#endif
4751#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4752 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4753#endif
4754#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4755 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4756#endif
4757#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4758 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4759#endif
4760#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4761 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4762#endif
4763#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4764 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4765#endif
4766#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4767 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4768#endif
4769#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4770 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4771#endif
4772#ifdef _CS_XBS5_LP64_OFF64_LIBS
4773 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4774#endif
4775#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4776 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4777#endif
4778#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4779 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4780#endif
4781#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4782 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4783#endif
4784#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4785 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4786#endif
4787#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4788 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4789#endif
Fred Draked86ed291999-12-15 15:34:33 +00004790#ifdef _MIPS_CS_AVAIL_PROCESSORS
4791 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4792#endif
4793#ifdef _MIPS_CS_BASE
4794 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4795#endif
4796#ifdef _MIPS_CS_HOSTID
4797 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4798#endif
4799#ifdef _MIPS_CS_HW_NAME
4800 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4801#endif
4802#ifdef _MIPS_CS_NUM_PROCESSORS
4803 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4804#endif
4805#ifdef _MIPS_CS_OSREL_MAJ
4806 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4807#endif
4808#ifdef _MIPS_CS_OSREL_MIN
4809 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4810#endif
4811#ifdef _MIPS_CS_OSREL_PATCH
4812 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4813#endif
4814#ifdef _MIPS_CS_OS_NAME
4815 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4816#endif
4817#ifdef _MIPS_CS_OS_PROVIDER
4818 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4819#endif
4820#ifdef _MIPS_CS_PROCESSORS
4821 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4822#endif
4823#ifdef _MIPS_CS_SERIAL
4824 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4825#endif
4826#ifdef _MIPS_CS_VENDOR
4827 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4828#endif
Fred Drakec9680921999-12-13 16:37:25 +00004829};
4830
4831static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004832conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004833{
4834 return conv_confname(arg, valuep, posix_constants_confstr,
4835 sizeof(posix_constants_confstr)
4836 / sizeof(struct constdef));
4837}
4838
4839static char posix_confstr__doc__[] = "\
4840confstr(name) -> string\n\
4841Return a string-valued system configuration variable.";
4842
4843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004844posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004845{
4846 PyObject *result = NULL;
4847 int name;
4848 char buffer[64];
4849
4850 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4851 int len = confstr(name, buffer, sizeof(buffer));
4852
Fred Drakec9680921999-12-13 16:37:25 +00004853 errno = 0;
4854 if (len == 0) {
4855 if (errno != 0)
4856 posix_error();
4857 else
4858 result = PyString_FromString("");
4859 }
4860 else {
4861 if (len >= sizeof(buffer)) {
4862 result = PyString_FromStringAndSize(NULL, len);
4863 if (result != NULL)
4864 confstr(name, PyString_AS_STRING(result), len+1);
4865 }
4866 else
4867 result = PyString_FromString(buffer);
4868 }
4869 }
4870 return result;
4871}
4872#endif
4873
4874
4875#ifdef HAVE_SYSCONF
4876static struct constdef posix_constants_sysconf[] = {
4877#ifdef _SC_2_CHAR_TERM
4878 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4879#endif
4880#ifdef _SC_2_C_BIND
4881 {"SC_2_C_BIND", _SC_2_C_BIND},
4882#endif
4883#ifdef _SC_2_C_DEV
4884 {"SC_2_C_DEV", _SC_2_C_DEV},
4885#endif
4886#ifdef _SC_2_C_VERSION
4887 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4888#endif
4889#ifdef _SC_2_FORT_DEV
4890 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4891#endif
4892#ifdef _SC_2_FORT_RUN
4893 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4894#endif
4895#ifdef _SC_2_LOCALEDEF
4896 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4897#endif
4898#ifdef _SC_2_SW_DEV
4899 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4900#endif
4901#ifdef _SC_2_UPE
4902 {"SC_2_UPE", _SC_2_UPE},
4903#endif
4904#ifdef _SC_2_VERSION
4905 {"SC_2_VERSION", _SC_2_VERSION},
4906#endif
Fred Draked86ed291999-12-15 15:34:33 +00004907#ifdef _SC_ABI_ASYNCHRONOUS_IO
4908 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4909#endif
4910#ifdef _SC_ACL
4911 {"SC_ACL", _SC_ACL},
4912#endif
Fred Drakec9680921999-12-13 16:37:25 +00004913#ifdef _SC_AIO_LISTIO_MAX
4914 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4915#endif
Fred Drakec9680921999-12-13 16:37:25 +00004916#ifdef _SC_AIO_MAX
4917 {"SC_AIO_MAX", _SC_AIO_MAX},
4918#endif
4919#ifdef _SC_AIO_PRIO_DELTA_MAX
4920 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4921#endif
4922#ifdef _SC_ARG_MAX
4923 {"SC_ARG_MAX", _SC_ARG_MAX},
4924#endif
4925#ifdef _SC_ASYNCHRONOUS_IO
4926 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4927#endif
4928#ifdef _SC_ATEXIT_MAX
4929 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4930#endif
Fred Draked86ed291999-12-15 15:34:33 +00004931#ifdef _SC_AUDIT
4932 {"SC_AUDIT", _SC_AUDIT},
4933#endif
Fred Drakec9680921999-12-13 16:37:25 +00004934#ifdef _SC_AVPHYS_PAGES
4935 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4936#endif
4937#ifdef _SC_BC_BASE_MAX
4938 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4939#endif
4940#ifdef _SC_BC_DIM_MAX
4941 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4942#endif
4943#ifdef _SC_BC_SCALE_MAX
4944 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4945#endif
4946#ifdef _SC_BC_STRING_MAX
4947 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4948#endif
Fred Draked86ed291999-12-15 15:34:33 +00004949#ifdef _SC_CAP
4950 {"SC_CAP", _SC_CAP},
4951#endif
Fred Drakec9680921999-12-13 16:37:25 +00004952#ifdef _SC_CHARCLASS_NAME_MAX
4953 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4954#endif
4955#ifdef _SC_CHAR_BIT
4956 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4957#endif
4958#ifdef _SC_CHAR_MAX
4959 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4960#endif
4961#ifdef _SC_CHAR_MIN
4962 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4963#endif
4964#ifdef _SC_CHILD_MAX
4965 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4966#endif
4967#ifdef _SC_CLK_TCK
4968 {"SC_CLK_TCK", _SC_CLK_TCK},
4969#endif
4970#ifdef _SC_COHER_BLKSZ
4971 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4972#endif
4973#ifdef _SC_COLL_WEIGHTS_MAX
4974 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4975#endif
4976#ifdef _SC_DCACHE_ASSOC
4977 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4978#endif
4979#ifdef _SC_DCACHE_BLKSZ
4980 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4981#endif
4982#ifdef _SC_DCACHE_LINESZ
4983 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4984#endif
4985#ifdef _SC_DCACHE_SZ
4986 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4987#endif
4988#ifdef _SC_DCACHE_TBLKSZ
4989 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4990#endif
4991#ifdef _SC_DELAYTIMER_MAX
4992 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4993#endif
4994#ifdef _SC_EQUIV_CLASS_MAX
4995 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4996#endif
4997#ifdef _SC_EXPR_NEST_MAX
4998 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4999#endif
5000#ifdef _SC_FSYNC
5001 {"SC_FSYNC", _SC_FSYNC},
5002#endif
5003#ifdef _SC_GETGR_R_SIZE_MAX
5004 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5005#endif
5006#ifdef _SC_GETPW_R_SIZE_MAX
5007 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5008#endif
5009#ifdef _SC_ICACHE_ASSOC
5010 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5011#endif
5012#ifdef _SC_ICACHE_BLKSZ
5013 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5014#endif
5015#ifdef _SC_ICACHE_LINESZ
5016 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5017#endif
5018#ifdef _SC_ICACHE_SZ
5019 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5020#endif
Fred Draked86ed291999-12-15 15:34:33 +00005021#ifdef _SC_INF
5022 {"SC_INF", _SC_INF},
5023#endif
Fred Drakec9680921999-12-13 16:37:25 +00005024#ifdef _SC_INT_MAX
5025 {"SC_INT_MAX", _SC_INT_MAX},
5026#endif
5027#ifdef _SC_INT_MIN
5028 {"SC_INT_MIN", _SC_INT_MIN},
5029#endif
5030#ifdef _SC_IOV_MAX
5031 {"SC_IOV_MAX", _SC_IOV_MAX},
5032#endif
Fred Draked86ed291999-12-15 15:34:33 +00005033#ifdef _SC_IP_SECOPTS
5034 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5035#endif
Fred Drakec9680921999-12-13 16:37:25 +00005036#ifdef _SC_JOB_CONTROL
5037 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5038#endif
Fred Draked86ed291999-12-15 15:34:33 +00005039#ifdef _SC_KERN_POINTERS
5040 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5041#endif
5042#ifdef _SC_KERN_SIM
5043 {"SC_KERN_SIM", _SC_KERN_SIM},
5044#endif
Fred Drakec9680921999-12-13 16:37:25 +00005045#ifdef _SC_LINE_MAX
5046 {"SC_LINE_MAX", _SC_LINE_MAX},
5047#endif
5048#ifdef _SC_LOGIN_NAME_MAX
5049 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5050#endif
5051#ifdef _SC_LOGNAME_MAX
5052 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5053#endif
5054#ifdef _SC_LONG_BIT
5055 {"SC_LONG_BIT", _SC_LONG_BIT},
5056#endif
Fred Draked86ed291999-12-15 15:34:33 +00005057#ifdef _SC_MAC
5058 {"SC_MAC", _SC_MAC},
5059#endif
Fred Drakec9680921999-12-13 16:37:25 +00005060#ifdef _SC_MAPPED_FILES
5061 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5062#endif
5063#ifdef _SC_MAXPID
5064 {"SC_MAXPID", _SC_MAXPID},
5065#endif
5066#ifdef _SC_MB_LEN_MAX
5067 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5068#endif
5069#ifdef _SC_MEMLOCK
5070 {"SC_MEMLOCK", _SC_MEMLOCK},
5071#endif
5072#ifdef _SC_MEMLOCK_RANGE
5073 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5074#endif
5075#ifdef _SC_MEMORY_PROTECTION
5076 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5077#endif
5078#ifdef _SC_MESSAGE_PASSING
5079 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5080#endif
Fred Draked86ed291999-12-15 15:34:33 +00005081#ifdef _SC_MMAP_FIXED_ALIGNMENT
5082 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5083#endif
Fred Drakec9680921999-12-13 16:37:25 +00005084#ifdef _SC_MQ_OPEN_MAX
5085 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5086#endif
5087#ifdef _SC_MQ_PRIO_MAX
5088 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5089#endif
Fred Draked86ed291999-12-15 15:34:33 +00005090#ifdef _SC_NACLS_MAX
5091 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5092#endif
Fred Drakec9680921999-12-13 16:37:25 +00005093#ifdef _SC_NGROUPS_MAX
5094 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5095#endif
5096#ifdef _SC_NL_ARGMAX
5097 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5098#endif
5099#ifdef _SC_NL_LANGMAX
5100 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5101#endif
5102#ifdef _SC_NL_MSGMAX
5103 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5104#endif
5105#ifdef _SC_NL_NMAX
5106 {"SC_NL_NMAX", _SC_NL_NMAX},
5107#endif
5108#ifdef _SC_NL_SETMAX
5109 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5110#endif
5111#ifdef _SC_NL_TEXTMAX
5112 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5113#endif
5114#ifdef _SC_NPROCESSORS_CONF
5115 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5116#endif
5117#ifdef _SC_NPROCESSORS_ONLN
5118 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5119#endif
Fred Draked86ed291999-12-15 15:34:33 +00005120#ifdef _SC_NPROC_CONF
5121 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5122#endif
5123#ifdef _SC_NPROC_ONLN
5124 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5125#endif
Fred Drakec9680921999-12-13 16:37:25 +00005126#ifdef _SC_NZERO
5127 {"SC_NZERO", _SC_NZERO},
5128#endif
5129#ifdef _SC_OPEN_MAX
5130 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5131#endif
5132#ifdef _SC_PAGESIZE
5133 {"SC_PAGESIZE", _SC_PAGESIZE},
5134#endif
5135#ifdef _SC_PAGE_SIZE
5136 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5137#endif
5138#ifdef _SC_PASS_MAX
5139 {"SC_PASS_MAX", _SC_PASS_MAX},
5140#endif
5141#ifdef _SC_PHYS_PAGES
5142 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5143#endif
5144#ifdef _SC_PII
5145 {"SC_PII", _SC_PII},
5146#endif
5147#ifdef _SC_PII_INTERNET
5148 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5149#endif
5150#ifdef _SC_PII_INTERNET_DGRAM
5151 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5152#endif
5153#ifdef _SC_PII_INTERNET_STREAM
5154 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5155#endif
5156#ifdef _SC_PII_OSI
5157 {"SC_PII_OSI", _SC_PII_OSI},
5158#endif
5159#ifdef _SC_PII_OSI_CLTS
5160 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5161#endif
5162#ifdef _SC_PII_OSI_COTS
5163 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5164#endif
5165#ifdef _SC_PII_OSI_M
5166 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5167#endif
5168#ifdef _SC_PII_SOCKET
5169 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5170#endif
5171#ifdef _SC_PII_XTI
5172 {"SC_PII_XTI", _SC_PII_XTI},
5173#endif
5174#ifdef _SC_POLL
5175 {"SC_POLL", _SC_POLL},
5176#endif
5177#ifdef _SC_PRIORITIZED_IO
5178 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5179#endif
5180#ifdef _SC_PRIORITY_SCHEDULING
5181 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5182#endif
5183#ifdef _SC_REALTIME_SIGNALS
5184 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5185#endif
5186#ifdef _SC_RE_DUP_MAX
5187 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5188#endif
5189#ifdef _SC_RTSIG_MAX
5190 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5191#endif
5192#ifdef _SC_SAVED_IDS
5193 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5194#endif
5195#ifdef _SC_SCHAR_MAX
5196 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5197#endif
5198#ifdef _SC_SCHAR_MIN
5199 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5200#endif
5201#ifdef _SC_SELECT
5202 {"SC_SELECT", _SC_SELECT},
5203#endif
5204#ifdef _SC_SEMAPHORES
5205 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5206#endif
5207#ifdef _SC_SEM_NSEMS_MAX
5208 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5209#endif
5210#ifdef _SC_SEM_VALUE_MAX
5211 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5212#endif
5213#ifdef _SC_SHARED_MEMORY_OBJECTS
5214 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5215#endif
5216#ifdef _SC_SHRT_MAX
5217 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5218#endif
5219#ifdef _SC_SHRT_MIN
5220 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5221#endif
5222#ifdef _SC_SIGQUEUE_MAX
5223 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5224#endif
5225#ifdef _SC_SIGRT_MAX
5226 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5227#endif
5228#ifdef _SC_SIGRT_MIN
5229 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5230#endif
Fred Draked86ed291999-12-15 15:34:33 +00005231#ifdef _SC_SOFTPOWER
5232 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5233#endif
Fred Drakec9680921999-12-13 16:37:25 +00005234#ifdef _SC_SPLIT_CACHE
5235 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5236#endif
5237#ifdef _SC_SSIZE_MAX
5238 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5239#endif
5240#ifdef _SC_STACK_PROT
5241 {"SC_STACK_PROT", _SC_STACK_PROT},
5242#endif
5243#ifdef _SC_STREAM_MAX
5244 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5245#endif
5246#ifdef _SC_SYNCHRONIZED_IO
5247 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5248#endif
5249#ifdef _SC_THREADS
5250 {"SC_THREADS", _SC_THREADS},
5251#endif
5252#ifdef _SC_THREAD_ATTR_STACKADDR
5253 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5254#endif
5255#ifdef _SC_THREAD_ATTR_STACKSIZE
5256 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5257#endif
5258#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5259 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5260#endif
5261#ifdef _SC_THREAD_KEYS_MAX
5262 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5263#endif
5264#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5265 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5266#endif
5267#ifdef _SC_THREAD_PRIO_INHERIT
5268 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5269#endif
5270#ifdef _SC_THREAD_PRIO_PROTECT
5271 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5272#endif
5273#ifdef _SC_THREAD_PROCESS_SHARED
5274 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5275#endif
5276#ifdef _SC_THREAD_SAFE_FUNCTIONS
5277 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5278#endif
5279#ifdef _SC_THREAD_STACK_MIN
5280 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5281#endif
5282#ifdef _SC_THREAD_THREADS_MAX
5283 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5284#endif
5285#ifdef _SC_TIMERS
5286 {"SC_TIMERS", _SC_TIMERS},
5287#endif
5288#ifdef _SC_TIMER_MAX
5289 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5290#endif
5291#ifdef _SC_TTY_NAME_MAX
5292 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5293#endif
5294#ifdef _SC_TZNAME_MAX
5295 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5296#endif
5297#ifdef _SC_T_IOV_MAX
5298 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5299#endif
5300#ifdef _SC_UCHAR_MAX
5301 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5302#endif
5303#ifdef _SC_UINT_MAX
5304 {"SC_UINT_MAX", _SC_UINT_MAX},
5305#endif
5306#ifdef _SC_UIO_MAXIOV
5307 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5308#endif
5309#ifdef _SC_ULONG_MAX
5310 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5311#endif
5312#ifdef _SC_USHRT_MAX
5313 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5314#endif
5315#ifdef _SC_VERSION
5316 {"SC_VERSION", _SC_VERSION},
5317#endif
5318#ifdef _SC_WORD_BIT
5319 {"SC_WORD_BIT", _SC_WORD_BIT},
5320#endif
5321#ifdef _SC_XBS5_ILP32_OFF32
5322 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5323#endif
5324#ifdef _SC_XBS5_ILP32_OFFBIG
5325 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5326#endif
5327#ifdef _SC_XBS5_LP64_OFF64
5328 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5329#endif
5330#ifdef _SC_XBS5_LPBIG_OFFBIG
5331 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5332#endif
5333#ifdef _SC_XOPEN_CRYPT
5334 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5335#endif
5336#ifdef _SC_XOPEN_ENH_I18N
5337 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5338#endif
5339#ifdef _SC_XOPEN_LEGACY
5340 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5341#endif
5342#ifdef _SC_XOPEN_REALTIME
5343 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5344#endif
5345#ifdef _SC_XOPEN_REALTIME_THREADS
5346 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5347#endif
5348#ifdef _SC_XOPEN_SHM
5349 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5350#endif
5351#ifdef _SC_XOPEN_UNIX
5352 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5353#endif
5354#ifdef _SC_XOPEN_VERSION
5355 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5356#endif
5357#ifdef _SC_XOPEN_XCU_VERSION
5358 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5359#endif
5360#ifdef _SC_XOPEN_XPG2
5361 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5362#endif
5363#ifdef _SC_XOPEN_XPG3
5364 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5365#endif
5366#ifdef _SC_XOPEN_XPG4
5367 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5368#endif
5369};
5370
5371static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005372conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005373{
5374 return conv_confname(arg, valuep, posix_constants_sysconf,
5375 sizeof(posix_constants_sysconf)
5376 / sizeof(struct constdef));
5377}
5378
5379static char posix_sysconf__doc__[] = "\
5380sysconf(name) -> integer\n\
5381Return an integer-valued system configuration variable.";
5382
5383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005384posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005385{
5386 PyObject *result = NULL;
5387 int name;
5388
5389 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5390 int value;
5391
5392 errno = 0;
5393 value = sysconf(name);
5394 if (value == -1 && errno != 0)
5395 posix_error();
5396 else
5397 result = PyInt_FromLong(value);
5398 }
5399 return result;
5400}
5401#endif
5402
5403
Fred Drakebec628d1999-12-15 18:31:10 +00005404/* This code is used to ensure that the tables of configuration value names
5405 * are in sorted order as required by conv_confname(), and also to build the
5406 * the exported dictionaries that are used to publish information about the
5407 * names available on the host platform.
5408 *
5409 * Sorting the table at runtime ensures that the table is properly ordered
5410 * when used, even for platforms we're not able to test on. It also makes
5411 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005412 */
Fred Drakebec628d1999-12-15 18:31:10 +00005413
5414static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005415cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005416{
5417 const struct constdef *c1 =
5418 (const struct constdef *) v1;
5419 const struct constdef *c2 =
5420 (const struct constdef *) v2;
5421
5422 return strcmp(c1->name, c2->name);
5423}
5424
5425static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005426setup_confname_table(struct constdef *table, size_t tablesize,
5427 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005428{
Fred Drakebec628d1999-12-15 18:31:10 +00005429 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005430 size_t i;
5431 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005432
5433 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5434 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005435 if (d == NULL)
5436 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005437
Barry Warsaw3155db32000-04-13 15:20:40 +00005438 for (i=0; i < tablesize; ++i) {
5439 PyObject *o = PyInt_FromLong(table[i].value);
5440 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5441 Py_XDECREF(o);
5442 Py_DECREF(d);
5443 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005444 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005445 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005446 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005447 status = PyDict_SetItemString(moddict, tablename, d);
5448 Py_DECREF(d);
5449 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005450}
5451
Fred Drakebec628d1999-12-15 18:31:10 +00005452/* Return -1 on failure, 0 on success. */
5453static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005454setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005455{
5456#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005457 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005458 sizeof(posix_constants_pathconf)
5459 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005460 "pathconf_names", moddict))
5461 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005462#endif
5463#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005464 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005465 sizeof(posix_constants_confstr)
5466 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005467 "confstr_names", moddict))
5468 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005469#endif
5470#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005471 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005472 sizeof(posix_constants_sysconf)
5473 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005474 "sysconf_names", moddict))
5475 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005476#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005477 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005478}
Fred Draked86ed291999-12-15 15:34:33 +00005479
5480
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005481static char posix_abort__doc__[] = "\
5482abort() -> does not return!\n\
5483Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5484in the hardest way possible on the hosting operating system.";
5485
5486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005487posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005488{
5489 if (!PyArg_ParseTuple(args, ":abort"))
5490 return NULL;
5491 abort();
5492 /*NOTREACHED*/
5493 Py_FatalError("abort() called from Python code didn't abort!");
5494 return NULL;
5495}
Fred Drakebec628d1999-12-15 18:31:10 +00005496
Tim Petersf58a7aa2000-09-22 10:05:54 +00005497#ifdef MS_WIN32
5498static char win32_startfile__doc__[] = "\
5499startfile(filepath) - Start a file with its associated application.\n\
5500\n\
5501This acts like double-clicking the file in Explorer, or giving the file\n\
5502name as an argument to the DOS \"start\" command: the file is opened\n\
5503with whatever application (if any) its extension is associated.\n\
5504\n\
5505startfile returns as soon as the associated application is launched.\n\
5506There is no option to wait for the application to close, and no way\n\
5507to retrieve the application's exit status.\n\
5508\n\
5509The filepath is relative to the current directory. If you want to use\n\
5510an absolute path, make sure the first character is not a slash (\"/\");\n\
5511the underlying Win32 ShellExecute function doesn't work if it is.";
5512
5513static PyObject *
5514win32_startfile(PyObject *self, PyObject *args)
5515{
5516 char *filepath;
5517 HINSTANCE rc;
5518 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5519 return NULL;
5520 Py_BEGIN_ALLOW_THREADS
5521 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5522 Py_END_ALLOW_THREADS
5523 if (rc <= (HINSTANCE)32)
5524 return win32_error("startfile", filepath);
5525 Py_INCREF(Py_None);
5526 return Py_None;
5527}
5528#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005529
5530static PyMethodDef posix_methods[] = {
5531 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5532#ifdef HAVE_TTYNAME
5533 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5534#endif
5535 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5536 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005537#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005538 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005539#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005540#ifdef HAVE_CHROOT
5541 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5542#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005543#ifdef HAVE_CTERMID
5544 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5545#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005546#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005547 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005548#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005549#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005550 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005551#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005552 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5553 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5554 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005555#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005556 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005557#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005558#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005559 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005560#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005561 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5562 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5563 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005564#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005565 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005566#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005567#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005568 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005569#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005570 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005571#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005572 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005573#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005574 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5575 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5576 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005577#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005578 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005579#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005580 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005581#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005582 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5583 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005584#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005585#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005586 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5587 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005588#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005589#ifdef HAVE_FORK1
5590 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5591#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005592#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005593 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005594#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005595#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005596 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005597#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005598#ifdef HAVE_FORKPTY
5599 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5600#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005601#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005602 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005603#endif /* HAVE_GETEGID */
5604#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005605 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005606#endif /* HAVE_GETEUID */
5607#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005608 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005609#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005610#ifdef HAVE_GETGROUPS
5611 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5612#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005613 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005614#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005615 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005616#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005617#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005618 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005619#endif /* HAVE_GETPPID */
5620#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005621 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005622#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005623#ifdef HAVE_GETLOGIN
5624 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5625#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005626#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005627 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005628#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005629#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005630 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005631#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005632#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005633 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005634#ifdef MS_WIN32
5635 {"popen2", win32_popen2, METH_VARARGS},
5636 {"popen3", win32_popen3, METH_VARARGS},
5637 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005638 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005639#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005640#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005641#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005642 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005643#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005644#ifdef HAVE_SETEUID
5645 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5646#endif /* HAVE_SETEUID */
5647#ifdef HAVE_SETEGID
5648 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5649#endif /* HAVE_SETEGID */
5650#ifdef HAVE_SETREUID
5651 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5652#endif /* HAVE_SETREUID */
5653#ifdef HAVE_SETREGID
5654 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5655#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005656#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005657 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005658#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005659#ifdef HAVE_SETGROUPS
5660 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5661#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005662#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005663 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005664#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005665#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005666 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005667#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005668#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005669 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005670#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005671#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005672 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005673#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005674#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005675 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005676#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005677#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005678 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005679#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005680#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005681 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005682#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005683 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5684 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5685 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5686 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5687 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5688 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5689 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5690 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5691 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005692 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005693#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005694 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005695#endif
5696#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005697 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005698#endif
5699#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005700 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005701#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005702#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005703 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005704#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005705#ifdef HAVE_UNSETENV
5706 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
5707#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005708#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005709 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005710#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005711#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005712 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005713#endif
5714#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005715 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005716#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005717#ifdef HAVE_SYS_WAIT_H
5718#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005719 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005720#endif /* WIFSTOPPED */
5721#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005722 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005723#endif /* WIFSIGNALED */
5724#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005725 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005726#endif /* WIFEXITED */
5727#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005728 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005729#endif /* WEXITSTATUS */
5730#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005731 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005732#endif /* WTERMSIG */
5733#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005734 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005735#endif /* WSTOPSIG */
5736#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005737#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005738 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005739#endif
5740#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005741 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005742#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005743#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005744 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5745#endif
5746#ifdef HAVE_TEMPNAM
5747 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5748#endif
5749#ifdef HAVE_TMPNAM
5750 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5751#endif
Fred Drakec9680921999-12-13 16:37:25 +00005752#ifdef HAVE_CONFSTR
5753 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5754#endif
5755#ifdef HAVE_SYSCONF
5756 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5757#endif
5758#ifdef HAVE_FPATHCONF
5759 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5760#endif
5761#ifdef HAVE_PATHCONF
5762 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5763#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005764 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005765#ifdef MS_WIN32
5766 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5767#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005768 {NULL, NULL} /* Sentinel */
5769};
5770
5771
Barry Warsaw4a342091996-12-19 23:50:02 +00005772static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005773ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005774{
5775 PyObject* v = PyInt_FromLong(value);
5776 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5777 return -1; /* triggers fatal error */
5778
5779 Py_DECREF(v);
5780 return 0;
5781}
5782
Guido van Rossumd48f2521997-12-05 22:19:34 +00005783#if defined(PYOS_OS2)
5784/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5785static int insertvalues(PyObject *d)
5786{
5787 APIRET rc;
5788 ULONG values[QSV_MAX+1];
5789 PyObject *v;
5790 char *ver, tmp[10];
5791
5792 Py_BEGIN_ALLOW_THREADS
5793 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5794 Py_END_ALLOW_THREADS
5795
5796 if (rc != NO_ERROR) {
5797 os2_error(rc);
5798 return -1;
5799 }
5800
5801 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5802 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5803 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5804 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5805 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5806 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5807 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5808
5809 switch (values[QSV_VERSION_MINOR]) {
5810 case 0: ver = "2.00"; break;
5811 case 10: ver = "2.10"; break;
5812 case 11: ver = "2.11"; break;
5813 case 30: ver = "3.00"; break;
5814 case 40: ver = "4.00"; break;
5815 case 50: ver = "5.00"; break;
5816 default:
5817 sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5818 values[QSV_VERSION_MINOR]);
5819 ver = &tmp[0];
5820 }
5821
5822 /* Add Indicator of the Version of the Operating System */
5823 v = PyString_FromString(ver);
5824 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5825 return -1;
5826 Py_DECREF(v);
5827
5828 /* Add Indicator of Which Drive was Used to Boot the System */
5829 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5830 tmp[1] = ':';
5831 tmp[2] = '\0';
5832
5833 v = PyString_FromString(tmp);
5834 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5835 return -1;
5836 Py_DECREF(v);
5837
5838 return 0;
5839}
5840#endif
5841
Barry Warsaw4a342091996-12-19 23:50:02 +00005842static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005843all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005844{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005845#ifdef F_OK
5846 if (ins(d, "F_OK", (long)F_OK)) return -1;
5847#endif
5848#ifdef R_OK
5849 if (ins(d, "R_OK", (long)R_OK)) return -1;
5850#endif
5851#ifdef W_OK
5852 if (ins(d, "W_OK", (long)W_OK)) return -1;
5853#endif
5854#ifdef X_OK
5855 if (ins(d, "X_OK", (long)X_OK)) return -1;
5856#endif
Fred Drakec9680921999-12-13 16:37:25 +00005857#ifdef NGROUPS_MAX
5858 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5859#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005860#ifdef TMP_MAX
5861 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5862#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005863#ifdef WNOHANG
5864 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5865#endif
5866#ifdef O_RDONLY
5867 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5868#endif
5869#ifdef O_WRONLY
5870 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5871#endif
5872#ifdef O_RDWR
5873 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5874#endif
5875#ifdef O_NDELAY
5876 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5877#endif
5878#ifdef O_NONBLOCK
5879 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5880#endif
5881#ifdef O_APPEND
5882 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5883#endif
5884#ifdef O_DSYNC
5885 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5886#endif
5887#ifdef O_RSYNC
5888 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5889#endif
5890#ifdef O_SYNC
5891 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5892#endif
5893#ifdef O_NOCTTY
5894 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5895#endif
5896#ifdef O_CREAT
5897 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5898#endif
5899#ifdef O_EXCL
5900 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5901#endif
5902#ifdef O_TRUNC
5903 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5904#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005905#ifdef O_BINARY
5906 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5907#endif
5908#ifdef O_TEXT
5909 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5910#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005911#ifdef O_LARGEFILE
5912 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
5913#endif
5914
5915/* GNU extensions. */
5916#ifdef O_DIRECT
5917 /* Direct disk access. */
5918 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
5919#endif
5920#ifdef O_DIRECTORY
5921 /* Must be a directory. */
5922 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
5923#endif
5924#ifdef O_NOFOLLOW
5925 /* Do not follow links. */
5926 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
5927#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005928
Guido van Rossum246bc171999-02-01 23:54:31 +00005929#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005930 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5931 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5932 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5933 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5934 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005935#endif
5936
Guido van Rossumd48f2521997-12-05 22:19:34 +00005937#if defined(PYOS_OS2)
5938 if (insertvalues(d)) return -1;
5939#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005940 return 0;
5941}
5942
5943
Tim Peters58e0a8c2001-05-14 22:32:33 +00005944#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005945#define INITFUNC initnt
5946#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005947
5948#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005949#define INITFUNC initos2
5950#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005951
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005952#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005953#define INITFUNC initposix
5954#define MODNAME "posix"
5955#endif
5956
Guido van Rossum3886bb61998-12-04 18:50:17 +00005957DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005958INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005959{
Barry Warsaw53699e91996-12-10 23:23:01 +00005960 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005961
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005962 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005963 posix_methods,
5964 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005965 (PyObject *)NULL,
5966 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005967 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005968
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005969 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005970 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005971 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005972 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005973 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005974
Barry Warsaw4a342091996-12-19 23:50:02 +00005975 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005976 return;
5977
Fred Drakebec628d1999-12-15 18:31:10 +00005978 if (setup_confname_tables(d))
5979 return;
5980
Barry Warsawca74da41999-02-09 19:31:45 +00005981 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005982
Guido van Rossumb3d39562000-01-31 18:41:26 +00005983#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005984 if (posix_putenv_garbage == NULL)
5985 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005986#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005987
5988 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
5989 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
5990
5991 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
5992 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005993}