blob: 08b0c4675d6a5f45c7bf79b5686f0d0f2073d474 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004/* This file is also used for Windows NT and MS-Win. In that case the module
Guido van Rossumad0ee831995-03-01 10:34:45 +00005 actually calls itself 'nt', not 'posix', and a few functions are
6 either unimplemented or implemented differently. The source
Guido van Rossum8d665e61996-06-26 18:22:49 +00007 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Guido van Rossuma4916fa1996-05-23 22:58:55 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Guido van Rossuma4916fa1996-05-23 22:58:55 +000011/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000013static char posix__doc__ [] =
14"This module provides access to operating system functionality that is\n\
15standardized by the C Standard and the POSIX standard (a thinly\n\
16disguised Unix interface). Refer to the library manual and\n\
17corresponding Unix manual entries for more information on calls.";
18
Barry Warsaw53699e91996-12-10 23:23:01 +000019#include "Python.h"
Guido van Rossum98bf58f2001-10-18 20:34:25 +000020#include "structseq.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000021
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000022#if defined(PYOS_OS2)
23#define INCL_DOS
24#define INCL_DOSERRORS
25#define INCL_DOSPROCESS
26#define INCL_NOPMAPI
27#include <os2.h>
28#endif
29
Guido van Rossumb6775db1994-08-01 11:34:53 +000030#include <sys/types.h>
31#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000032
Guido van Rossum36bc6801995-06-14 22:54:23 +000033#ifdef HAVE_SYS_WAIT_H
34#include <sys/wait.h> /* For WNOHANG */
35#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000036
Guido van Rossuma376cc51996-12-05 23:43:35 +000037#ifdef HAVE_SIGNAL_H
38#include <signal.h>
39#endif
40
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#ifdef HAVE_FCNTL_H
42#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000043#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000044
Guido van Rossuma6535fd2001-10-18 19:44:10 +000045#ifdef HAVE_GRP_H
46#include <grp.h>
47#endif
48
Skip Montanaro8216c182001-02-27 17:04:34 +000049/* pick up declaration of confstr on some systems? */
50#ifdef HAVE_UNISTD_H
51#include <unistd.h>
52#endif /* HAVE_UNISTD_H */
53
Guido van Rossuma4916fa1996-05-23 22:58:55 +000054/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000055/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000056#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000057#include <process.h>
58#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000059#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000060#define HAVE_GETCWD 1
61#define HAVE_OPENDIR 1
62#define HAVE_SYSTEM 1
63#if defined(__OS2__)
64#define HAVE_EXECV 1
65#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000066#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000067#include <process.h>
68#else
69#ifdef __BORLANDC__ /* Borland compiler */
70#define HAVE_EXECV 1
71#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072#define HAVE_OPENDIR 1
73#define HAVE_PIPE 1
74#define HAVE_POPEN 1
75#define HAVE_SYSTEM 1
76#define HAVE_WAIT 1
77#else
78#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000079#define HAVE_GETCWD 1
80#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000081#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#define HAVE_EXECV 1
83#define HAVE_PIPE 1
84#define HAVE_POPEN 1
85#define HAVE_SYSTEM 1
86#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000087#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#else /* all other compilers */
89/* Unix functions that the configure script doesn't check for */
90#define HAVE_EXECV 1
91#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000092#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
93#define HAVE_FORK1 1
94#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000095#define HAVE_GETCWD 1
96#define HAVE_GETEGID 1
97#define HAVE_GETEUID 1
98#define HAVE_GETGID 1
99#define HAVE_GETPPID 1
100#define HAVE_GETUID 1
101#define HAVE_KILL 1
102#define HAVE_OPENDIR 1
103#define HAVE_PIPE 1
104#define HAVE_POPEN 1
105#define HAVE_SYSTEM 1
106#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000107#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000108#endif /* _MSC_VER */
109#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000110#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000111#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000112
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000114
Guido van Rossumb6775db1994-08-01 11:34:53 +0000115#ifdef HAVE_UNISTD_H
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000116#include <unistd.h>
Guido van Rossum36bc6801995-06-14 22:54:23 +0000117#endif
118
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000119#if defined(sun) && !defined(__SVR4)
120/* SunOS 4.1.4 doesn't have prototypes for these: */
121extern int rename(const char *, const char *);
122extern int pclose(FILE *);
123extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000124extern int fsync(int);
125extern int lstat(const char *, struct stat *);
126extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000127#endif
128
Guido van Rossum36bc6801995-06-14 22:54:23 +0000129#ifdef NeXT
130/* NeXT's <unistd.h> and <utime.h> aren't worth much */
131#undef HAVE_UNISTD_H
132#undef HAVE_UTIME_H
Guido van Rossumb9f866c1997-05-22 15:12:39 +0000133#define HAVE_WAITPID
Guido van Rossum36bc6801995-06-14 22:54:23 +0000134/* #undef HAVE_GETCWD */
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000135#define UNION_WAIT /* This should really be checked for by autoconf */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000136#endif
137
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000138#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000155#ifdef __BORLANDC__
156extern int chmod(const char *, int);
157#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000159#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int chown(const char *, uid_t, gid_t);
161extern char *getcwd(char *, int);
162extern char *strerror(int);
163extern int link(const char *, const char *);
164extern int rename(const char *, const char *);
165extern int stat(const char *, struct stat *);
166extern int unlink(const char *);
167extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000170#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000173#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000175
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178#ifdef HAVE_UTIME_H
179#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000182#ifdef HAVE_SYS_UTIME_H
183#include <sys/utime.h>
184#define HAVE_UTIME_H /* pretend we do for the rest of this file */
185#endif /* HAVE_SYS_UTIME_H */
186
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187#ifdef HAVE_SYS_TIMES_H
188#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_PARAM_H
192#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifdef HAVE_SYS_UTSNAME_H
196#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
199#ifndef MAXPATHLEN
200#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000201#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000203#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000207#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000208#include <direct.h>
209#define NAMLEN(dirent) strlen((dirent)->d_name)
210#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000214#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000216#endif
217#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000219#endif
220#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000222#endif
223#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <direct.h>
227#include <io.h>
228#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000229#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000231#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000233#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#else /* 16-bit Windows */
235#include <dos.h>
236#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000237#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
Guido van Rossumd48f2521997-12-05 22:19:34 +0000240#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000242#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000244#ifdef UNION_WAIT
245/* Emulate some macros on systems that have a union instead of macros */
246
247#ifndef WIFEXITED
248#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
249#endif
250
251#ifndef WEXITSTATUS
252#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
253#endif
254
255#ifndef WTERMSIG
256#define WTERMSIG(u_wait) ((u_wait).w_termsig)
257#endif
258
259#endif /* UNION_WAIT */
260
Greg Wardb48bc172000-03-01 21:51:56 +0000261/* Don't use the "_r" form if we don't need it (also, won't have a
262 prototype for it, at least on Solaris -- maybe others as well?). */
263#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
264#define USE_CTERMID_R
265#endif
266
267#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
268#define USE_TMPNAM_R
269#endif
270
Fred Drake699f3522000-06-29 21:12:41 +0000271/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000272#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000273#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000274# define STAT _stati64
275# define FSTAT _fstati64
276# define STRUCT_STAT struct _stati64
277#else
278# define STAT stat
279# define FSTAT fstat
280# define STRUCT_STAT struct stat
281#endif
282
283
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284/* Return a dictionary corresponding to the POSIX environment table */
285
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000286#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000288#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289
Barry Warsaw53699e91996-12-10 23:23:01 +0000290static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000291convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292{
Barry Warsaw53699e91996-12-10 23:23:01 +0000293 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000295 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296 if (d == NULL)
297 return NULL;
298 if (environ == NULL)
299 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000300 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000302 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000303 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 char *p = strchr(*e, '=');
305 if (p == NULL)
306 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000307 k = PyString_FromStringAndSize(*e, (int)(p-*e));
308 if (k == NULL) {
309 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000311 }
312 v = PyString_FromString(p+1);
313 if (v == NULL) {
314 PyErr_Clear();
315 Py_DECREF(k);
316 continue;
317 }
318 if (PyDict_GetItem(d, k) == NULL) {
319 if (PyDict_SetItem(d, k, v) != 0)
320 PyErr_Clear();
321 }
322 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000323 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000325#if defined(PYOS_OS2)
326 {
327 APIRET rc;
328 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
329
330 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000331 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000332 PyObject *v = PyString_FromString(buffer);
333 PyDict_SetItemString(d, "BEGINLIBPATH", v);
334 Py_DECREF(v);
335 }
336 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
337 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
338 PyObject *v = PyString_FromString(buffer);
339 PyDict_SetItemString(d, "ENDLIBPATH", v);
340 Py_DECREF(v);
341 }
342 }
343#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000344 return d;
345}
346
347
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000348/* Set a POSIX-specific error from errno, and return NULL */
349
Barry Warsawd58d7641998-07-23 16:14:40 +0000350static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000351posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000352{
Barry Warsawca74da41999-02-09 19:31:45 +0000353 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354}
Barry Warsawd58d7641998-07-23 16:14:40 +0000355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000356posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000357{
Barry Warsawca74da41999-02-09 19:31:45 +0000358 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000359}
360
Mark Hammondef8b6542001-05-13 08:04:26 +0000361static PyObject *
362posix_error_with_allocated_filename(char* name)
363{
364 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
365 PyMem_Free(name);
366 return rc;
367}
368
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000369#ifdef MS_WIN32
370static PyObject *
371win32_error(char* function, char* filename)
372{
Mark Hammond33a6da92000-08-15 00:46:38 +0000373 /* XXX We should pass the function name along in the future.
374 (_winreg.c also wants to pass the function name.)
375 This would however require an additional param to the
376 Windows error object, which is non-trivial.
377 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000378 errno = GetLastError();
379 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000380 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000381 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000382 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000383}
384#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385
Guido van Rossumd48f2521997-12-05 22:19:34 +0000386#if defined(PYOS_OS2)
387/**********************************************************************
388 * Helper Function to Trim and Format OS/2 Messages
389 **********************************************************************/
390 static void
391os2_formatmsg(char *msgbuf, int msglen, char *reason)
392{
393 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
394
395 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
396 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
397
398 while (lastc > msgbuf && isspace(*lastc))
399 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
400 }
401
402 /* Add Optional Reason Text */
403 if (reason) {
404 strcat(msgbuf, " : ");
405 strcat(msgbuf, reason);
406 }
407}
408
409/**********************************************************************
410 * Decode an OS/2 Operating System Error Code
411 *
412 * A convenience function to lookup an OS/2 error code and return a
413 * text message we can use to raise a Python exception.
414 *
415 * Notes:
416 * The messages for errors returned from the OS/2 kernel reside in
417 * the file OSO001.MSG in the \OS2 directory hierarchy.
418 *
419 **********************************************************************/
420 static char *
421os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
422{
423 APIRET rc;
424 ULONG msglen;
425
426 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
427 Py_BEGIN_ALLOW_THREADS
428 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
429 errorcode, "oso001.msg", &msglen);
430 Py_END_ALLOW_THREADS
431
432 if (rc == NO_ERROR)
433 os2_formatmsg(msgbuf, msglen, reason);
434 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000435 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000436 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000437
438 return msgbuf;
439}
440
441/* Set an OS/2-specific error and return NULL. OS/2 kernel
442 errors are not in a global variable e.g. 'errno' nor are
443 they congruent with posix error numbers. */
444
445static PyObject * os2_error(int code)
446{
447 char text[1024];
448 PyObject *v;
449
450 os2_strerror(text, sizeof(text), code, "");
451
452 v = Py_BuildValue("(is)", code, text);
453 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000454 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000455 Py_DECREF(v);
456 }
457 return NULL; /* Signal to Python that an Exception is Pending */
458}
459
460#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461
462/* POSIX generic methods */
463
Barry Warsaw53699e91996-12-10 23:23:01 +0000464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000465posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000466{
467 int fd;
468 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000469 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000470 return NULL;
471 Py_BEGIN_ALLOW_THREADS
472 res = (*func)(fd);
473 Py_END_ALLOW_THREADS
474 if (res < 0)
475 return posix_error();
476 Py_INCREF(Py_None);
477 return Py_None;
478}
479
480
481static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000482posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000483{
Mark Hammondef8b6542001-05-13 08:04:26 +0000484 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000485 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000486 if (!PyArg_ParseTuple(args, format,
487 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000488 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000489 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000490 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000491 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000492 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000493 return posix_error_with_allocated_filename(path1);
494 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000495 Py_INCREF(Py_None);
496 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497}
498
Barry Warsaw53699e91996-12-10 23:23:01 +0000499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000500posix_2str(PyObject *args, char *format,
501 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502{
Mark Hammondef8b6542001-05-13 08:04:26 +0000503 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000504 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000505 if (!PyArg_ParseTuple(args, format,
506 Py_FileSystemDefaultEncoding, &path1,
507 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000508 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000509 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000510 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000511 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000512 PyMem_Free(path1);
513 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000514 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000515 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000516 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000517 Py_INCREF(Py_None);
518 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000519}
520
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000521static char stat_result__doc__[] =
522"stat_result: Result from stat or lstat.\n\n\
523This object may be accessed either as a tuple of\n\
524 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
525or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
526\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000527Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000528they are available as attributes only.\n\
529\n\
530See os.stat for more information.\n";
531
532static PyStructSequence_Field stat_result_fields[] = {
533 {"st_mode", "protection bits"},
534 {"st_ino", "inode"},
535 {"st_dev", "device"},
536 {"st_nlink", "number of hard links"},
537 {"st_uid", "user ID of owner"},
538 {"st_gid", "group ID of owner"},
539 {"st_size", "total size, in bytes"},
540 {"st_atime", "time of last access"},
541 {"st_mtime", "time of last modification"},
542 {"st_ctime", "time of last change"},
543#ifdef HAVE_ST_BLKSIZE
544 {"st_blksize", "blocksize for filesystem I/O"},
545#endif
546#ifdef HAVE_ST_BLOCKS
547 {"st_blocks", "number of blocks allocated"},
548#endif
549#ifdef HAVE_ST_RDEV
550 {"st_rdev", "device type (if inode device)"},
551#endif
552 {0}
553};
554
555#ifdef HAVE_ST_BLKSIZE
556#define ST_BLKSIZE_IDX 10
557#else
558#define ST_BLKSIZE_IDX 9
559#endif
560
561#ifdef HAVE_ST_BLOCKS
562#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
563#else
564#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
565#endif
566
567#ifdef HAVE_ST_RDEV
568#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
569#else
570#define ST_RDEV_IDX ST_BLOCKS_IDX
571#endif
572
573static PyStructSequence_Desc stat_result_desc = {
574 "stat_result", /* name */
575 stat_result__doc__, /* doc */
576 stat_result_fields,
577 10
578};
579
580static char statvfs_result__doc__[] =
581"statvfs_result: Result from statvfs or fstatvfs.\n\n\
582This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000583 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
584or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000585\n\
586See os.statvfs for more information.\n";
587
588static PyStructSequence_Field statvfs_result_fields[] = {
589 {"f_bsize", },
590 {"f_frsize", },
591 {"f_blocks", },
592 {"f_bfree", },
593 {"f_bavail", },
594 {"f_files", },
595 {"f_ffree", },
596 {"f_favail", },
597 {"f_flag", },
598 {"f_namemax",},
599 {0}
600};
601
602static PyStructSequence_Desc statvfs_result_desc = {
603 "statvfs_result", /* name */
604 statvfs_result__doc__, /* doc */
605 statvfs_result_fields,
606 10
607};
608
609static PyTypeObject StatResultType;
610static PyTypeObject StatVFSResultType;
611
Fred Drake699f3522000-06-29 21:12:41 +0000612/* pack a system stat C structure into the Python stat tuple
613 (used by posix_stat() and posix_fstat()) */
614static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000615_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000616{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000617 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000618 if (v == NULL)
619 return NULL;
620
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000621 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000622#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000623 PyStructSequence_SET_ITEM(v, 1,
624 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000625#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000626 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000627#endif
628#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000629 PyStructSequence_SET_ITEM(v, 2,
630 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000631#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000632 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000633#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000634 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
635 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
636 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000637#ifdef HAVE_LARGEFILE_SUPPORT
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000638 PyStructSequence_SET_ITEM(v, 6,
639 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000640#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000641 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000642#endif
643#if SIZEOF_TIME_T > SIZEOF_LONG
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000644 PyStructSequence_SET_ITEM(v, 7,
645 PyLong_FromLongLong((LONG_LONG)st.st_atime));
646 PyStructSequence_SET_ITEM(v, 8,
647 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
648 PyStructSequence_SET_ITEM(v, 9,
649 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000650#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000651 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
652 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
653 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
654#endif
655
656#ifdef HAVE_ST_BLKSIZE
657 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
658 PyInt_FromLong((long)st.st_blksize));
659#endif
660#ifdef HAVE_ST_BLOCKS
661 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
662 PyInt_FromLong((long)st.st_blocks));
663#endif
664#ifdef HAVE_ST_RDEV
665 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
666 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000667#endif
668
669 if (PyErr_Occurred()) {
670 Py_DECREF(v);
671 return NULL;
672 }
673
674 return v;
675}
676
Barry Warsaw53699e91996-12-10 23:23:01 +0000677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000678posix_do_stat(PyObject *self, PyObject *args, char *format,
679 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000680{
Fred Drake699f3522000-06-29 21:12:41 +0000681 STRUCT_STAT st;
Mark Hammondef8b6542001-05-13 08:04:26 +0000682 char *path = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000683 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000684
685#ifdef MS_WIN32
686 int pathlen;
687 char pathcopy[MAX_PATH];
688#endif /* MS_WIN32 */
689
Mark Hammondef8b6542001-05-13 08:04:26 +0000690 if (!PyArg_ParseTuple(args, format,
691 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000692 return NULL;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000693
694#ifdef MS_WIN32
695 pathlen = strlen(path);
696 /* the library call can blow up if the file name is too long! */
697 if (pathlen > MAX_PATH) {
Mark Hammondef8b6542001-05-13 08:04:26 +0000698 PyMem_Free(path);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000699 errno = ENAMETOOLONG;
700 return posix_error();
701 }
702
703 if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
Guido van Rossum19dde102000-05-03 02:44:55 +0000704 /* exception for specific or current drive root */
705 if (!((pathlen == 1) ||
706 ((pathlen == 3) &&
Guido van Rossumace88ae2000-04-21 18:54:45 +0000707 (path[1] == ':') &&
Guido van Rossum19dde102000-05-03 02:44:55 +0000708 (path[2] == '\\' || path[2] == '/'))))
Guido van Rossumace88ae2000-04-21 18:54:45 +0000709 {
710 strncpy(pathcopy, path, pathlen);
711 pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
712 path = pathcopy;
713 }
714 }
715#endif /* MS_WIN32 */
716
Barry Warsaw53699e91996-12-10 23:23:01 +0000717 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000718 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000719 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000720 if (res != 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000721 return posix_error_with_allocated_filename(path);
Fred Drake699f3522000-06-29 21:12:41 +0000722
Mark Hammondef8b6542001-05-13 08:04:26 +0000723 PyMem_Free(path);
Fred Drake699f3522000-06-29 21:12:41 +0000724 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000725}
726
727
728/* POSIX methods */
729
Guido van Rossum94f6f721999-01-06 18:42:14 +0000730static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000731"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000732Test for access to a file.";
733
734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000735posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000736{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000737 char *path;
738 int mode;
739 int res;
740
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000741 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000742 return NULL;
743 Py_BEGIN_ALLOW_THREADS
744 res = access(path, mode);
745 Py_END_ALLOW_THREADS
746 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000747}
748
Guido van Rossumd371ff11999-01-25 16:12:23 +0000749#ifndef F_OK
750#define F_OK 0
751#endif
752#ifndef R_OK
753#define R_OK 4
754#endif
755#ifndef W_OK
756#define W_OK 2
757#endif
758#ifndef X_OK
759#define X_OK 1
760#endif
761
762#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000763static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000764"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000765Return the name of the terminal device connected to 'fd'.";
766
767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000768posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000769{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000770 int id;
771 char *ret;
772
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000773 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000774 return NULL;
775
Guido van Rossum94f6f721999-01-06 18:42:14 +0000776 ret = ttyname(id);
777 if (ret == NULL)
778 return(posix_error());
779 return(PyString_FromString(ret));
780}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000781#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000782
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000783#ifdef HAVE_CTERMID
784static char posix_ctermid__doc__[] =
785"ctermid() -> String\n\
786Return the name of the controlling terminal for this process.";
787
788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000789posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000790{
791 char *ret;
792 char buffer[L_ctermid];
793
794 if (!PyArg_ParseTuple(args, ":ctermid"))
795 return NULL;
796
Greg Wardb48bc172000-03-01 21:51:56 +0000797#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000798 ret = ctermid_r(buffer);
799#else
800 ret = ctermid(buffer);
801#endif
802 if (ret == NULL)
803 return(posix_error());
804 return(PyString_FromString(buffer));
805}
806#endif
807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000808static char posix_chdir__doc__[] =
809"chdir(path) -> None\n\
810Change the current working directory to the specified path.";
811
Barry Warsaw53699e91996-12-10 23:23:01 +0000812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000813posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000814{
Mark Hammondef8b6542001-05-13 08:04:26 +0000815 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000816}
817
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000818
819static char posix_chmod__doc__[] =
820"chmod(path, mode) -> None\n\
821Change the access permissions of a file.";
822
Barry Warsaw53699e91996-12-10 23:23:01 +0000823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000824posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000825{
Mark Hammondef8b6542001-05-13 08:04:26 +0000826 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000827 int i;
828 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000829 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
830 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000831 return NULL;
832 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000833 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000834 Py_END_ALLOW_THREADS
835 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000836 return posix_error_with_allocated_filename(path);
837 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000838 Py_INCREF(Py_None);
839 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000840}
841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000842
Martin v. Löwis244edc82001-10-04 22:44:26 +0000843#ifdef HAVE_CHROOT
844static char posix_chroot__doc__[] =
845"chroot(path) -> None\n\
846Change root directory to path.";
847
848static PyObject *
849posix_chroot(PyObject *self, PyObject *args)
850{
851 return posix_1str(args, "et:chroot", chroot);
852}
853#endif
854
Guido van Rossum21142a01999-01-08 21:05:37 +0000855#ifdef HAVE_FSYNC
856static char posix_fsync__doc__[] =
857"fsync(fildes) -> None\n\
858force write of file with filedescriptor to disk.";
859
860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000861posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000862{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000863 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000864}
865#endif /* HAVE_FSYNC */
866
867#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000868
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000869#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000870extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
871#endif
872
Guido van Rossum21142a01999-01-08 21:05:37 +0000873static char posix_fdatasync__doc__[] =
874"fdatasync(fildes) -> None\n\
875force write of file with filedescriptor to disk.\n\
876 does not force update of metadata.";
877
878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000879posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000880{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000881 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000882}
883#endif /* HAVE_FDATASYNC */
884
885
Fredrik Lundh10723342000-07-10 16:38:09 +0000886#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000887static char posix_chown__doc__[] =
888"chown(path, uid, gid) -> None\n\
889Change the owner and group id of path to the numeric uid and gid.";
890
Barry Warsaw53699e91996-12-10 23:23:01 +0000891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000892posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000893{
Mark Hammondef8b6542001-05-13 08:04:26 +0000894 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000895 int uid, gid;
896 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000897 if (!PyArg_ParseTuple(args, "etii:chown",
898 Py_FileSystemDefaultEncoding, &path,
899 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000900 return NULL;
901 Py_BEGIN_ALLOW_THREADS
902 res = chown(path, (uid_t) uid, (gid_t) gid);
903 Py_END_ALLOW_THREADS
904 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000905 return posix_error_with_allocated_filename(path);
906 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000907 Py_INCREF(Py_None);
908 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000909}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000910#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000912
Guido van Rossum36bc6801995-06-14 22:54:23 +0000913#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000914static char posix_getcwd__doc__[] =
915"getcwd() -> path\n\
916Return a string representing the current working directory.";
917
Barry Warsaw53699e91996-12-10 23:23:01 +0000918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000919posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920{
921 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000922 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000923 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000924 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000925 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000926 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000927 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000928 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000929 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000930 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000931}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000932#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000934
Guido van Rossumb6775db1994-08-01 11:34:53 +0000935#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000936static char posix_link__doc__[] =
937"link(src, dst) -> None\n\
938Create a hard link to a file.";
939
Barry Warsaw53699e91996-12-10 23:23:01 +0000940static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000941posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000942{
Mark Hammondef8b6542001-05-13 08:04:26 +0000943 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000944}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000945#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000947
948static char posix_listdir__doc__[] =
949"listdir(path) -> list_of_strings\n\
950Return a list containing the names of the entries in the directory.\n\
951\n\
952 path: path of directory to list\n\
953\n\
954The list is in arbitrary order. It does not include the special\n\
955entries '.' and '..' even if they are present in the directory.";
956
Barry Warsaw53699e91996-12-10 23:23:01 +0000957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000958posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000959{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000960 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000961 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000962#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000963
Barry Warsaw53699e91996-12-10 23:23:01 +0000964 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000965 HANDLE hFindFile;
966 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000967 /* MAX_PATH characters could mean a bigger encoded string */
968 char namebuf[MAX_PATH*2+5];
969 char *bufptr = namebuf;
970 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000971 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000972
Mark Hammondef8b6542001-05-13 08:04:26 +0000973 if (!PyArg_ParseTuple(args, "et#:listdir",
974 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000975 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000976 ch = namebuf[len-1];
977 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000978 namebuf[len++] = '/';
979 strcpy(namebuf + len, "*.*");
980
Barry Warsaw53699e91996-12-10 23:23:01 +0000981 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000982 return NULL;
983
984 hFindFile = FindFirstFile(namebuf, &FileData);
985 if (hFindFile == INVALID_HANDLE_VALUE) {
986 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000987 if (errno == ERROR_FILE_NOT_FOUND)
988 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000989 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000990 }
991 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000992 if (FileData.cFileName[0] == '.' &&
993 (FileData.cFileName[1] == '\0' ||
994 FileData.cFileName[1] == '.' &&
995 FileData.cFileName[2] == '\0'))
996 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000997 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000998 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000999 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001000 d = NULL;
1001 break;
1002 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001003 if (PyList_Append(d, v) != 0) {
1004 Py_DECREF(v);
1005 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001006 d = NULL;
1007 break;
1008 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001009 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001010 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1011
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001012 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001013 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001014
1015 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001016
Tim Peters0bb44a42000-09-15 07:44:49 +00001017#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001018
1019#ifndef MAX_PATH
1020#define MAX_PATH 250
1021#endif
1022 char *name, *pt;
1023 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001024 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001025 char namebuf[MAX_PATH+5];
1026 struct _find_t ep;
1027
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001028 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001029 return NULL;
1030 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001031 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001032 return NULL;
1033 }
1034 strcpy(namebuf, name);
1035 for (pt = namebuf; *pt; pt++)
1036 if (*pt == '/')
1037 *pt = '\\';
1038 if (namebuf[len-1] != '\\')
1039 namebuf[len++] = '\\';
1040 strcpy(namebuf + len, "*.*");
1041
Barry Warsaw53699e91996-12-10 23:23:01 +00001042 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001043 return NULL;
1044
1045 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001046 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1047 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001048 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001049 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001050 }
1051 do {
1052 if (ep.name[0] == '.' &&
1053 (ep.name[1] == '\0' ||
1054 ep.name[1] == '.' &&
1055 ep.name[2] == '\0'))
1056 continue;
1057 strcpy(namebuf, ep.name);
1058 for (pt = namebuf; *pt; pt++)
1059 if (isupper(*pt))
1060 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001061 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001062 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001063 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001064 d = NULL;
1065 break;
1066 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001067 if (PyList_Append(d, v) != 0) {
1068 Py_DECREF(v);
1069 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001070 d = NULL;
1071 break;
1072 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001073 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001074 } while (_dos_findnext(&ep) == 0);
1075
1076 return d;
1077
Tim Peters0bb44a42000-09-15 07:44:49 +00001078#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001079
1080#ifndef MAX_PATH
1081#define MAX_PATH CCHMAXPATH
1082#endif
1083 char *name, *pt;
1084 int len;
1085 PyObject *d, *v;
1086 char namebuf[MAX_PATH+5];
1087 HDIR hdir = 1;
1088 ULONG srchcnt = 1;
1089 FILEFINDBUF3 ep;
1090 APIRET rc;
1091
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001092 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001093 return NULL;
1094 if (len >= MAX_PATH) {
1095 PyErr_SetString(PyExc_ValueError, "path too long");
1096 return NULL;
1097 }
1098 strcpy(namebuf, name);
1099 for (pt = namebuf; *pt; pt++)
1100 if (*pt == '/')
1101 *pt = '\\';
1102 if (namebuf[len-1] != '\\')
1103 namebuf[len++] = '\\';
1104 strcpy(namebuf + len, "*.*");
1105
1106 if ((d = PyList_New(0)) == NULL)
1107 return NULL;
1108
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001109 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1110 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001111 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001112 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1113 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1114 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001115
1116 if (rc != NO_ERROR) {
1117 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001118 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001119 }
1120
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001121 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001122 do {
1123 if (ep.achName[0] == '.'
1124 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001125 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001126
1127 strcpy(namebuf, ep.achName);
1128
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001129 /* Leave Case of Name Alone -- In Native Form */
1130 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001131
1132 v = PyString_FromString(namebuf);
1133 if (v == NULL) {
1134 Py_DECREF(d);
1135 d = NULL;
1136 break;
1137 }
1138 if (PyList_Append(d, v) != 0) {
1139 Py_DECREF(v);
1140 Py_DECREF(d);
1141 d = NULL;
1142 break;
1143 }
1144 Py_DECREF(v);
1145 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1146 }
1147
1148 return d;
1149#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001150
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001151 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001152 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001153 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001154 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001155 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001156 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001157 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001158 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001159 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001160 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001161 closedir(dirp);
1162 return NULL;
1163 }
1164 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001165 if (ep->d_name[0] == '.' &&
1166 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001167 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001168 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001169 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001170 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001171 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001172 d = NULL;
1173 break;
1174 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001175 if (PyList_Append(d, v) != 0) {
1176 Py_DECREF(v);
1177 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178 d = NULL;
1179 break;
1180 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001181 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001182 }
1183 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001184
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001186
Tim Peters0bb44a42000-09-15 07:44:49 +00001187#endif /* which OS */
1188} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189
Mark Hammondef8b6542001-05-13 08:04:26 +00001190#ifdef MS_WIN32
1191/* A helper function for abspath on win32 */
1192static PyObject *
1193posix__getfullpathname(PyObject *self, PyObject *args)
1194{
1195 /* assume encoded strings wont more than double no of chars */
1196 char inbuf[MAX_PATH*2];
1197 char *inbufp = inbuf;
1198 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1199 char outbuf[MAX_PATH*2];
1200 char *temp;
1201 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1202 Py_FileSystemDefaultEncoding, &inbufp,
1203 &insize))
1204 return NULL;
1205 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1206 outbuf, &temp))
1207 return win32_error("GetFullPathName", inbuf);
1208 return PyString_FromString(outbuf);
1209} /* end of posix__getfullpathname */
1210#endif /* MS_WIN32 */
1211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001212static char posix_mkdir__doc__[] =
1213"mkdir(path [, mode=0777]) -> None\n\
1214Create a directory.";
1215
Barry Warsaw53699e91996-12-10 23:23:01 +00001216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001217posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001219 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001220 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001221 int mode = 0777;
Mark Hammondef8b6542001-05-13 08:04:26 +00001222 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1223 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001224 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001225 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001226#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001227 res = mkdir(path);
1228#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001229 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001230#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001231 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001232 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001233 return posix_error_with_allocated_filename(path);
1234 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001235 Py_INCREF(Py_None);
1236 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001237}
1238
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001239
Guido van Rossumb6775db1994-08-01 11:34:53 +00001240#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001241#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1242#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1243#include <sys/resource.h>
1244#endif
1245#endif
1246
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001247static char posix_nice__doc__[] =
1248"nice(inc) -> new_priority\n\
1249Decrease the priority of process and return new priority.";
1250
Barry Warsaw53699e91996-12-10 23:23:01 +00001251static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001252posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001253{
1254 int increment, value;
1255
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001256 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001257 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001258
1259 /* There are two flavours of 'nice': one that returns the new
1260 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001261 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1262 the use of getpriority() to get the new priority.
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001263
1264 If we are of the nice family that returns the new priority, we
1265 need to clear errno before the call, and check if errno is filled
1266 before calling posix_error() on a returnvalue of -1, because the
1267 -1 may be the actual new priority! */
1268
1269 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001270 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001271#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001272 if (value == 0)
1273 value = getpriority(PRIO_PROCESS, 0);
1274#endif
1275 if (value == -1 && errno != 0)
1276 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001277 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001278 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001279}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001280#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001281
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001282
1283static char posix_rename__doc__[] =
1284"rename(old, new) -> None\n\
1285Rename a file or directory.";
1286
Barry Warsaw53699e91996-12-10 23:23:01 +00001287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001288posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001289{
Mark Hammondef8b6542001-05-13 08:04:26 +00001290 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001291}
1292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001293
1294static char posix_rmdir__doc__[] =
1295"rmdir(path) -> None\n\
1296Remove a directory.";
1297
Barry Warsaw53699e91996-12-10 23:23:01 +00001298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001299posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001300{
Mark Hammondef8b6542001-05-13 08:04:26 +00001301 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001302}
1303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001304
1305static char posix_stat__doc__[] =
1306"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1307Perform a stat system call on the given path.";
1308
Barry Warsaw53699e91996-12-10 23:23:01 +00001309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001310posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001311{
Mark Hammondef8b6542001-05-13 08:04:26 +00001312 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001313}
1314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001315
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001316#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001317static char posix_system__doc__[] =
1318"system(command) -> exit_status\n\
1319Execute the command (a string) in a subshell.";
1320
Barry Warsaw53699e91996-12-10 23:23:01 +00001321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001322posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001323{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001324 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001325 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001326 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001327 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001328 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001329 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001330 Py_END_ALLOW_THREADS
1331 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001332}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001333#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
1336static char posix_umask__doc__[] =
1337"umask(new_mask) -> old_mask\n\
1338Set the current numeric umask and return the previous umask.";
1339
Barry Warsaw53699e91996-12-10 23:23:01 +00001340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001341posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342{
1343 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001344 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001345 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001346 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001347 if (i < 0)
1348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001349 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350}
1351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001352
1353static char posix_unlink__doc__[] =
1354"unlink(path) -> None\n\
1355Remove a file (same as remove(path)).";
1356
1357static char posix_remove__doc__[] =
1358"remove(path) -> None\n\
1359Remove a file (same as unlink(path)).";
1360
Barry Warsaw53699e91996-12-10 23:23:01 +00001361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001362posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001363{
Mark Hammondef8b6542001-05-13 08:04:26 +00001364 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365}
1366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001367
Guido van Rossumb6775db1994-08-01 11:34:53 +00001368#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001369static char posix_uname__doc__[] =
1370"uname() -> (sysname, nodename, release, version, machine)\n\
1371Return a tuple identifying the current operating system.";
1372
Barry Warsaw53699e91996-12-10 23:23:01 +00001373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001374posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001375{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001376 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001377 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001378 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001379 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001380 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001381 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001382 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001383 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001384 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001385 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001386 u.sysname,
1387 u.nodename,
1388 u.release,
1389 u.version,
1390 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001391}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001392#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001394
1395static char posix_utime__doc__[] =
1396"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001397utime(path, None) -> None\n\
1398Set the access and modified time of the file to the given values. If the\n\
1399second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001400
Barry Warsaw53699e91996-12-10 23:23:01 +00001401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001402posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001403{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001404 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001405 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001406 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001407 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001408
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001409/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001410#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001411 struct utimbuf buf;
1412#define ATIME buf.actime
1413#define MTIME buf.modtime
1414#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001415#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001416 time_t buf[2];
1417#define ATIME buf[0]
1418#define MTIME buf[1]
1419#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001420#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001421
Barry Warsaw3cef8562000-05-01 16:17:24 +00001422 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001424 if (arg == Py_None) {
1425 /* optional time values not given */
1426 Py_BEGIN_ALLOW_THREADS
1427 res = utime(path, NULL);
1428 Py_END_ALLOW_THREADS
1429 }
1430 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1431 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001432 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001433 return NULL;
1434 }
1435 else {
1436 ATIME = atime;
1437 MTIME = mtime;
1438 Py_BEGIN_ALLOW_THREADS
1439 res = utime(path, UTIME_ARG);
1440 Py_END_ALLOW_THREADS
1441 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001442 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001443 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001444 Py_INCREF(Py_None);
1445 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001446#undef UTIME_ARG
1447#undef ATIME
1448#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001449}
1450
Guido van Rossum85e3b011991-06-03 12:42:10 +00001451
Guido van Rossum3b066191991-06-04 19:40:25 +00001452/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001453
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001454static char posix__exit__doc__[] =
1455"_exit(status)\n\
1456Exit to the system with specified status, without normal exit processing.";
1457
Barry Warsaw53699e91996-12-10 23:23:01 +00001458static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001459posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001460{
1461 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001462 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001463 return NULL;
1464 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001465 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001466}
1467
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001468
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001469#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001470static char posix_execv__doc__[] =
1471"execv(path, args)\n\
1472Execute an executable path with arguments, replacing current process.\n\
1473\n\
1474 path: path of executable file\n\
1475 args: tuple or list of strings";
1476
Barry Warsaw53699e91996-12-10 23:23:01 +00001477static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001478posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001479{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001480 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001481 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001482 char **argvlist;
1483 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001484 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001485
Guido van Rossum89b33251993-10-22 14:26:06 +00001486 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001487 argv is a list or tuple of strings. */
1488
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001489 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001490 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001491 if (PyList_Check(argv)) {
1492 argc = PyList_Size(argv);
1493 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001494 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001495 else if (PyTuple_Check(argv)) {
1496 argc = PyTuple_Size(argv);
1497 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001498 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001499 else {
Fred Drake661ea262000-10-24 19:57:45 +00001500 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001501 return NULL;
1502 }
1503
1504 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001505 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001506 return NULL;
1507 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001508
Barry Warsaw53699e91996-12-10 23:23:01 +00001509 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001510 if (argvlist == NULL)
1511 return NULL;
1512 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001513 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1514 PyMem_DEL(argvlist);
Guido van Rossum50422b42000-04-26 20:34:28 +00001515 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001516 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001517 return NULL;
1518
Guido van Rossum85e3b011991-06-03 12:42:10 +00001519 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001520 }
1521 argvlist[argc] = NULL;
1522
Guido van Rossumb6775db1994-08-01 11:34:53 +00001523#ifdef BAD_EXEC_PROTOTYPES
1524 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001525#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001526 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001527#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001528
Guido van Rossum85e3b011991-06-03 12:42:10 +00001529 /* If we get here it's definitely an error */
1530
Barry Warsaw53699e91996-12-10 23:23:01 +00001531 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001532 return posix_error();
1533}
1534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001535
1536static char posix_execve__doc__[] =
1537"execve(path, args, env)\n\
1538Execute a path with arguments and environment, replacing current process.\n\
1539\n\
1540 path: path of executable file\n\
1541 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001542 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001543
Barry Warsaw53699e91996-12-10 23:23:01 +00001544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001545posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001546{
1547 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001548 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001549 char **argvlist;
1550 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001551 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001552 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001553 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001554
1555 /* execve has three arguments: (path, argv, env), where
1556 argv is a list or tuple of strings and env is a dictionary
1557 like posix.environ. */
1558
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001559 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001560 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001561 if (PyList_Check(argv)) {
1562 argc = PyList_Size(argv);
1563 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001564 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001565 else if (PyTuple_Check(argv)) {
1566 argc = PyTuple_Size(argv);
1567 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001568 }
1569 else {
Fred Drake661ea262000-10-24 19:57:45 +00001570 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001571 return NULL;
1572 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001573 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001574 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001575 return NULL;
1576 }
1577
Guido van Rossum50422b42000-04-26 20:34:28 +00001578 if (argc == 0) {
1579 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001580 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001581 return NULL;
1582 }
1583
Barry Warsaw53699e91996-12-10 23:23:01 +00001584 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001585 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001586 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001587 return NULL;
1588 }
1589 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001590 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001591 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001592 &argvlist[i]))
1593 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001594 goto fail_1;
1595 }
1596 }
1597 argvlist[argc] = NULL;
1598
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001599 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001600 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001602 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001603 goto fail_1;
1604 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001605 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001606 keys = PyMapping_Keys(env);
1607 vals = PyMapping_Values(env);
1608 if (!keys || !vals)
1609 goto fail_2;
1610
1611 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001612 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001613 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001614
1615 key = PyList_GetItem(keys, pos);
1616 val = PyList_GetItem(vals, pos);
1617 if (!key || !val)
1618 goto fail_2;
1619
Fred Drake661ea262000-10-24 19:57:45 +00001620 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1621 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001622 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001623 goto fail_2;
1624 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001625
1626#if defined(PYOS_OS2)
1627 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1628 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1629#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001630 len = PyString_Size(key) + PyString_Size(val) + 2;
1631 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001632 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001633 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001634 goto fail_2;
1635 }
Tim Petersc8996f52001-12-03 20:41:00 +00001636 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001637 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001638#if defined(PYOS_OS2)
1639 }
1640#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001641 }
1642 envlist[envc] = 0;
1643
Guido van Rossumb6775db1994-08-01 11:34:53 +00001644
1645#ifdef BAD_EXEC_PROTOTYPES
1646 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001647#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001648 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001649#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001650
1651 /* If we get here it's definitely an error */
1652
1653 (void) posix_error();
1654
1655 fail_2:
1656 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001657 PyMem_DEL(envlist[envc]);
1658 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001659 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001660 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001661 Py_XDECREF(vals);
1662 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001663 return NULL;
1664}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001665#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001667
Guido van Rossuma1065681999-01-25 23:20:23 +00001668#ifdef HAVE_SPAWNV
1669static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001670"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001671Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001672\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001673 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001674 path: path of executable file\n\
1675 args: tuple or list of strings";
1676
1677static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001678posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001679{
1680 char *path;
1681 PyObject *argv;
1682 char **argvlist;
1683 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001684 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001685 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001686
1687 /* spawnv has three arguments: (mode, path, argv), where
1688 argv is a list or tuple of strings. */
1689
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001690 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001691 return NULL;
1692 if (PyList_Check(argv)) {
1693 argc = PyList_Size(argv);
1694 getitem = PyList_GetItem;
1695 }
1696 else if (PyTuple_Check(argv)) {
1697 argc = PyTuple_Size(argv);
1698 getitem = PyTuple_GetItem;
1699 }
1700 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001701 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001702 return NULL;
1703 }
1704
1705 argvlist = PyMem_NEW(char *, argc+1);
1706 if (argvlist == NULL)
1707 return NULL;
1708 for (i = 0; i < argc; i++) {
1709 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1710 PyMem_DEL(argvlist);
Fred Drake137507e2000-06-01 02:02:46 +00001711 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001712 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001713 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001714 }
1715 }
1716 argvlist[argc] = NULL;
1717
Guido van Rossum246bc171999-02-01 23:54:31 +00001718 if (mode == _OLD_P_OVERLAY)
1719 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001720
1721 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001722 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001723 Py_END_ALLOW_THREADS
1724
Guido van Rossuma1065681999-01-25 23:20:23 +00001725 PyMem_DEL(argvlist);
1726
Fred Drake699f3522000-06-29 21:12:41 +00001727 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001728 return posix_error();
1729 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001730#if SIZEOF_LONG == SIZEOF_VOID_P
1731 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001732#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001733 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001734#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001735}
1736
1737
1738static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001739"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001740Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001741\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001742 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001743 path: path of executable file\n\
1744 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001745 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001746
1747static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001748posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001749{
1750 char *path;
1751 PyObject *argv, *env;
1752 char **argvlist;
1753 char **envlist;
1754 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1755 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001756 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001757 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001758
1759 /* spawnve has four arguments: (mode, path, argv, env), where
1760 argv is a list or tuple of strings and env is a dictionary
1761 like posix.environ. */
1762
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001763 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001764 return NULL;
1765 if (PyList_Check(argv)) {
1766 argc = PyList_Size(argv);
1767 getitem = PyList_GetItem;
1768 }
1769 else if (PyTuple_Check(argv)) {
1770 argc = PyTuple_Size(argv);
1771 getitem = PyTuple_GetItem;
1772 }
1773 else {
Fred Drake661ea262000-10-24 19:57:45 +00001774 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001775 return NULL;
1776 }
1777 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001778 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001779 return NULL;
1780 }
1781
1782 argvlist = PyMem_NEW(char *, argc+1);
1783 if (argvlist == NULL) {
1784 PyErr_NoMemory();
1785 return NULL;
1786 }
1787 for (i = 0; i < argc; i++) {
1788 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001789 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001790 &argvlist[i]))
1791 {
1792 goto fail_1;
1793 }
1794 }
1795 argvlist[argc] = NULL;
1796
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001797 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001798 envlist = PyMem_NEW(char *, i + 1);
1799 if (envlist == NULL) {
1800 PyErr_NoMemory();
1801 goto fail_1;
1802 }
1803 envc = 0;
1804 keys = PyMapping_Keys(env);
1805 vals = PyMapping_Values(env);
1806 if (!keys || !vals)
1807 goto fail_2;
1808
1809 for (pos = 0; pos < i; pos++) {
1810 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001811 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001812
1813 key = PyList_GetItem(keys, pos);
1814 val = PyList_GetItem(vals, pos);
1815 if (!key || !val)
1816 goto fail_2;
1817
Fred Drake661ea262000-10-24 19:57:45 +00001818 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1819 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001820 {
1821 goto fail_2;
1822 }
Tim Petersc8996f52001-12-03 20:41:00 +00001823 len = PyString_Size(key) + PyString_Size(val) + 2;
1824 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001825 if (p == NULL) {
1826 PyErr_NoMemory();
1827 goto fail_2;
1828 }
Tim Petersc8996f52001-12-03 20:41:00 +00001829 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001830 envlist[envc++] = p;
1831 }
1832 envlist[envc] = 0;
1833
Guido van Rossum246bc171999-02-01 23:54:31 +00001834 if (mode == _OLD_P_OVERLAY)
1835 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001836
1837 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001838 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001839 Py_END_ALLOW_THREADS
1840
Fred Drake699f3522000-06-29 21:12:41 +00001841 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001842 (void) posix_error();
1843 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001844#if SIZEOF_LONG == SIZEOF_VOID_P
1845 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001846#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001847 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001848#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001849
1850 fail_2:
1851 while (--envc >= 0)
1852 PyMem_DEL(envlist[envc]);
1853 PyMem_DEL(envlist);
1854 fail_1:
1855 PyMem_DEL(argvlist);
1856 Py_XDECREF(vals);
1857 Py_XDECREF(keys);
1858 return res;
1859}
1860#endif /* HAVE_SPAWNV */
1861
1862
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001863#ifdef HAVE_FORK1
1864static char posix_fork1__doc__[] =
1865"fork1() -> pid\n\
1866Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1867\n\
1868Return 0 to child process and PID of child to parent process.";
1869
1870static PyObject *
1871posix_fork1(self, args)
1872 PyObject *self;
1873 PyObject *args;
1874{
1875 int pid;
1876 if (!PyArg_ParseTuple(args, ":fork1"))
1877 return NULL;
1878 pid = fork1();
1879 if (pid == -1)
1880 return posix_error();
1881 PyOS_AfterFork();
1882 return PyInt_FromLong((long)pid);
1883}
1884#endif
1885
1886
Guido van Rossumad0ee831995-03-01 10:34:45 +00001887#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001888static char posix_fork__doc__[] =
1889"fork() -> pid\n\
1890Fork a child process.\n\
1891\n\
1892Return 0 to child process and PID of child to parent process.";
1893
Barry Warsaw53699e91996-12-10 23:23:01 +00001894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001895posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001896{
1897 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001898 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001899 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001900 pid = fork();
1901 if (pid == -1)
1902 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001903 if (pid == 0)
1904 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001905 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001906}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001907#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001908
Fred Drake8cef4cf2000-06-28 16:40:38 +00001909#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1910#ifdef HAVE_PTY_H
1911#include <pty.h>
1912#else
1913#ifdef HAVE_LIBUTIL_H
1914#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001915#endif /* HAVE_LIBUTIL_H */
1916#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001917#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001918
Thomas Wouters70c21a12000-07-14 14:28:33 +00001919#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001920static char posix_openpty__doc__[] =
1921"openpty() -> (master_fd, slave_fd)\n\
1922Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1923
1924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001925posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001926{
1927 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001928#ifndef HAVE_OPENPTY
1929 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001930#endif
1931
Fred Drake8cef4cf2000-06-28 16:40:38 +00001932 if (!PyArg_ParseTuple(args, ":openpty"))
1933 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001934
1935#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001936 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1937 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001938#else
1939 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1940 if (slave_name == NULL)
1941 return posix_error();
1942
1943 slave_fd = open(slave_name, O_RDWR);
1944 if (slave_fd < 0)
1945 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001946#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001947
Fred Drake8cef4cf2000-06-28 16:40:38 +00001948 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001949
Fred Drake8cef4cf2000-06-28 16:40:38 +00001950}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001951#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001952
1953#ifdef HAVE_FORKPTY
1954static char posix_forkpty__doc__[] =
1955"forkpty() -> (pid, master_fd)\n\
1956Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1957Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1958To both, return fd of newly opened pseudo-terminal.\n";
1959
1960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001961posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001962{
1963 int master_fd, pid;
1964
1965 if (!PyArg_ParseTuple(args, ":forkpty"))
1966 return NULL;
1967 pid = forkpty(&master_fd, NULL, NULL, NULL);
1968 if (pid == -1)
1969 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001970 if (pid == 0)
1971 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001972 return Py_BuildValue("(ii)", pid, master_fd);
1973}
1974#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001975
Guido van Rossumad0ee831995-03-01 10:34:45 +00001976#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001977static char posix_getegid__doc__[] =
1978"getegid() -> egid\n\
1979Return the current process's effective group id.";
1980
Barry Warsaw53699e91996-12-10 23:23:01 +00001981static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001982posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001983{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001984 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001985 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001986 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001987}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001988#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001990
Guido van Rossumad0ee831995-03-01 10:34:45 +00001991#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001992static char posix_geteuid__doc__[] =
1993"geteuid() -> euid\n\
1994Return the current process's effective user id.";
1995
Barry Warsaw53699e91996-12-10 23:23:01 +00001996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001997posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001998{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001999 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002000 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002001 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002002}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002003#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002004
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002005
Guido van Rossumad0ee831995-03-01 10:34:45 +00002006#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002007static char posix_getgid__doc__[] =
2008"getgid() -> gid\n\
2009Return the current process's group id.";
2010
Barry Warsaw53699e91996-12-10 23:23:01 +00002011static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002012posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002013{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002014 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002015 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002016 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002017}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002018#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002019
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002020
2021static char posix_getpid__doc__[] =
2022"getpid() -> pid\n\
2023Return the current process id";
2024
Barry Warsaw53699e91996-12-10 23:23:01 +00002025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002026posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002027{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002028 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002029 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002030 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002031}
2032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002033
Fred Drakec9680921999-12-13 16:37:25 +00002034#ifdef HAVE_GETGROUPS
2035static char posix_getgroups__doc__[] = "\
2036getgroups() -> list of group IDs\n\
2037Return list of supplemental group IDs for the process.";
2038
2039static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002040posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002041{
2042 PyObject *result = NULL;
2043
2044 if (PyArg_ParseTuple(args, ":getgroups")) {
2045#ifdef NGROUPS_MAX
2046#define MAX_GROUPS NGROUPS_MAX
2047#else
2048 /* defined to be 16 on Solaris7, so this should be a small number */
2049#define MAX_GROUPS 64
2050#endif
2051 gid_t grouplist[MAX_GROUPS];
2052 int n;
2053
2054 n = getgroups(MAX_GROUPS, grouplist);
2055 if (n < 0)
2056 posix_error();
2057 else {
2058 result = PyList_New(n);
2059 if (result != NULL) {
2060 PyObject *o;
2061 int i;
2062 for (i = 0; i < n; ++i) {
2063 o = PyInt_FromLong((long)grouplist[i]);
2064 if (o == NULL) {
2065 Py_DECREF(result);
2066 result = NULL;
2067 break;
2068 }
2069 PyList_SET_ITEM(result, i, o);
2070 }
2071 }
2072 }
2073 }
2074 return result;
2075}
2076#endif
2077
Guido van Rossumb6775db1994-08-01 11:34:53 +00002078#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002079static char posix_getpgrp__doc__[] =
2080"getpgrp() -> pgrp\n\
2081Return the current process group id.";
2082
Barry Warsaw53699e91996-12-10 23:23:01 +00002083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002084posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002085{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002086 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002087 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002088#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002089 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002090#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002091 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002092#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002093}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002094#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002096
Guido van Rossumb6775db1994-08-01 11:34:53 +00002097#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002098static char posix_setpgrp__doc__[] =
2099"setpgrp() -> None\n\
2100Make this process a session leader.";
2101
Barry Warsaw53699e91996-12-10 23:23:01 +00002102static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002103posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002104{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002105 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002106 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002107#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002108 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002109#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002110 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002111#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002112 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002113 Py_INCREF(Py_None);
2114 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002115}
2116
Guido van Rossumb6775db1994-08-01 11:34:53 +00002117#endif /* HAVE_SETPGRP */
2118
Guido van Rossumad0ee831995-03-01 10:34:45 +00002119#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002120static char posix_getppid__doc__[] =
2121"getppid() -> ppid\n\
2122Return the parent's process id.";
2123
Barry Warsaw53699e91996-12-10 23:23:01 +00002124static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002125posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002126{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002127 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002128 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002129 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002130}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002131#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002133
Fred Drake12c6e2d1999-12-14 21:25:03 +00002134#ifdef HAVE_GETLOGIN
2135static char posix_getlogin__doc__[] = "\
2136getlogin() -> string\n\
2137Return the actual login name.";
2138
2139static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002140posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002141{
2142 PyObject *result = NULL;
2143
2144 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002145 char *name;
2146 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002147
Fred Drakea30680b2000-12-06 21:24:28 +00002148 errno = 0;
2149 name = getlogin();
2150 if (name == NULL) {
2151 if (errno)
2152 posix_error();
2153 else
2154 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002155 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002156 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002157 else
2158 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002159 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002160 }
2161 return result;
2162}
2163#endif
2164
Guido van Rossumad0ee831995-03-01 10:34:45 +00002165#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002166static char posix_getuid__doc__[] =
2167"getuid() -> uid\n\
2168Return the current process's user id.";
2169
Barry Warsaw53699e91996-12-10 23:23:01 +00002170static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002171posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002172{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002173 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002174 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002175 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002176}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002177#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002179
Guido van Rossumad0ee831995-03-01 10:34:45 +00002180#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002181static char posix_kill__doc__[] =
2182"kill(pid, sig) -> None\n\
2183Kill a process with a signal.";
2184
Barry Warsaw53699e91996-12-10 23:23:01 +00002185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002186posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002187{
2188 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002189 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002190 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002191#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002192 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2193 APIRET rc;
2194 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002195 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002196
2197 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2198 APIRET rc;
2199 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002200 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002201
2202 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002203 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002204#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002205 if (kill(pid, sig) == -1)
2206 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002207#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002208 Py_INCREF(Py_None);
2209 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002210}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002211#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002212
Guido van Rossumc0125471996-06-28 18:55:32 +00002213#ifdef HAVE_PLOCK
2214
2215#ifdef HAVE_SYS_LOCK_H
2216#include <sys/lock.h>
2217#endif
2218
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002219static char posix_plock__doc__[] =
2220"plock(op) -> None\n\
2221Lock program segments into memory.";
2222
Barry Warsaw53699e91996-12-10 23:23:01 +00002223static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002224posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002225{
2226 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002227 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002228 return NULL;
2229 if (plock(op) == -1)
2230 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002231 Py_INCREF(Py_None);
2232 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002233}
2234#endif
2235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002236
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002237#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002238static char posix_popen__doc__[] =
2239"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2240Open a pipe to/from a command returning a file object.";
2241
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002242#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002243static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002244async_system(const char *command)
2245{
2246 char *p, errormsg[256], args[1024];
2247 RESULTCODES rcodes;
2248 APIRET rc;
2249 char *shell = getenv("COMSPEC");
2250 if (!shell)
2251 shell = "cmd";
2252
2253 strcpy(args, shell);
2254 p = &args[ strlen(args)+1 ];
2255 strcpy(p, "/c ");
2256 strcat(p, command);
2257 p += strlen(p) + 1;
2258 *p = '\0';
2259
2260 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002261 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002262 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002263 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002264 &rcodes, shell);
2265 return rc;
2266}
2267
Guido van Rossumd48f2521997-12-05 22:19:34 +00002268static FILE *
2269popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002270{
2271 HFILE rhan, whan;
2272 FILE *retfd = NULL;
2273 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2274
Guido van Rossumd48f2521997-12-05 22:19:34 +00002275 if (rc != NO_ERROR) {
2276 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002277 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002278 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002279
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002280 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2281 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002282
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002283 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2284 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002285
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002286 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2287 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002288
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002289 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002290 }
2291
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002292 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2293 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002294
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002295 if (rc == NO_ERROR)
2296 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2297
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002298 close(oldfd); /* And Close Saved STDOUT Handle */
2299 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002300
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002301 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2302 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002303
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002304 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2305 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002306
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002307 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2308 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002309
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002310 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002311 }
2312
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002313 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2314 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002315
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002316 if (rc == NO_ERROR)
2317 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2318
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002319 close(oldfd); /* And Close Saved STDIN Handle */
2320 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002321
Guido van Rossumd48f2521997-12-05 22:19:34 +00002322 } else {
2323 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002324 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002325 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002326}
2327
2328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002329posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002330{
2331 char *name;
2332 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002333 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002334 FILE *fp;
2335 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002336 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337 return NULL;
2338 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002339 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002340 Py_END_ALLOW_THREADS
2341 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002342 return os2_error(err);
2343
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002344 f = PyFile_FromFile(fp, name, mode, fclose);
2345 if (f != NULL)
2346 PyFile_SetBufSize(f, bufsize);
2347 return f;
2348}
2349
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002350#elif defined(MS_WIN32)
2351
2352/*
2353 * Portable 'popen' replacement for Win32.
2354 *
2355 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2356 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002357 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002358 */
2359
2360#include <malloc.h>
2361#include <io.h>
2362#include <fcntl.h>
2363
2364/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2365#define POPEN_1 1
2366#define POPEN_2 2
2367#define POPEN_3 3
2368#define POPEN_4 4
2369
2370static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002371static int _PyPclose(FILE *file);
2372
2373/*
2374 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002375 * for use when retrieving the process exit code. See _PyPclose() below
2376 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002377 */
2378static PyObject *_PyPopenProcs = NULL;
2379
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002380
2381/* popen that works from a GUI.
2382 *
2383 * The result of this function is a pipe (file) connected to the
2384 * processes stdin or stdout, depending on the requested mode.
2385 */
2386
2387static PyObject *
2388posix_popen(PyObject *self, PyObject *args)
2389{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002390 PyObject *f, *s;
2391 int tm = 0;
2392
2393 char *cmdstring;
2394 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002395 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002396 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002397 return NULL;
2398
2399 s = PyTuple_New(0);
2400
2401 if (*mode == 'r')
2402 tm = _O_RDONLY;
2403 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002404 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002405 return NULL;
2406 } else
2407 tm = _O_WRONLY;
2408
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002409 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002410 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002411 return NULL;
2412 }
2413
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002414 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002415 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002416 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002417 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002418 else
2419 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2420
2421 return f;
2422}
2423
2424/* Variation on win32pipe.popen
2425 *
2426 * The result of this function is a pipe (file) connected to the
2427 * process's stdin, and a pipe connected to the process's stdout.
2428 */
2429
2430static PyObject *
2431win32_popen2(PyObject *self, PyObject *args)
2432{
2433 PyObject *f;
2434 int tm=0;
2435
2436 char *cmdstring;
2437 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002438 int bufsize = -1;
2439 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002440 return NULL;
2441
2442 if (*mode == 't')
2443 tm = _O_TEXT;
2444 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002445 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002446 return NULL;
2447 } else
2448 tm = _O_BINARY;
2449
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002450 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002451 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002452 return NULL;
2453 }
2454
2455 f = _PyPopen(cmdstring, tm, POPEN_2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002456
2457 return f;
2458}
2459
2460/*
2461 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002462 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002463 * The result of this function is 3 pipes - the process's stdin,
2464 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002465 */
2466
2467static PyObject *
2468win32_popen3(PyObject *self, PyObject *args)
2469{
2470 PyObject *f;
2471 int tm = 0;
2472
2473 char *cmdstring;
2474 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002475 int bufsize = -1;
2476 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002477 return NULL;
2478
2479 if (*mode == 't')
2480 tm = _O_TEXT;
2481 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002482 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002483 return NULL;
2484 } else
2485 tm = _O_BINARY;
2486
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002487 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002488 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002489 return NULL;
2490 }
2491
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002492 f = _PyPopen(cmdstring, tm, POPEN_3);
2493
2494 return f;
2495}
2496
2497/*
2498 * Variation on win32pipe.popen
2499 *
2500 * The result of this function is 2 pipes - the processes stdin,
2501 * and stdout+stderr combined as a single pipe.
2502 */
2503
2504static PyObject *
2505win32_popen4(PyObject *self, PyObject *args)
2506{
2507 PyObject *f;
2508 int tm = 0;
2509
2510 char *cmdstring;
2511 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002512 int bufsize = -1;
2513 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002514 return NULL;
2515
2516 if (*mode == 't')
2517 tm = _O_TEXT;
2518 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002519 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002520 return NULL;
2521 } else
2522 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002523
2524 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002525 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002526 return NULL;
2527 }
2528
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002529 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002530
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002531 return f;
2532}
2533
Mark Hammond08501372001-01-31 07:30:29 +00002534static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002535_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002536 HANDLE hStdin,
2537 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002538 HANDLE hStderr,
2539 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002540{
2541 PROCESS_INFORMATION piProcInfo;
2542 STARTUPINFO siStartInfo;
2543 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002544 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002545 int i;
2546 int x;
2547
2548 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002549 char *comshell;
2550
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002551 s1 = (char *)_alloca(i);
2552 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2553 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002554
2555 /* Explicitly check if we are using COMMAND.COM. If we are
2556 * then use the w9xpopen hack.
2557 */
2558 comshell = s1 + x;
2559 while (comshell >= s1 && *comshell != '\\')
2560 --comshell;
2561 ++comshell;
2562
2563 if (GetVersion() < 0x80000000 &&
2564 _stricmp(comshell, "command.com") != 0) {
2565 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002566 x = i + strlen(s3) + strlen(cmdstring) + 1;
2567 s2 = (char *)_alloca(x);
2568 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002569 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002570 }
2571 else {
2572 /*
Tim Peters402d5982001-08-27 06:37:48 +00002573 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2574 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002575 */
Mark Hammond08501372001-01-31 07:30:29 +00002576 char modulepath[_MAX_PATH];
2577 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002578 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2579 for (i = x = 0; modulepath[i]; i++)
2580 if (modulepath[i] == '\\')
2581 x = i+1;
2582 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002583 /* Create the full-name to w9xpopen, so we can test it exists */
2584 strncat(modulepath,
2585 szConsoleSpawn,
2586 (sizeof(modulepath)/sizeof(modulepath[0]))
2587 -strlen(modulepath));
2588 if (stat(modulepath, &statinfo) != 0) {
2589 /* Eeek - file-not-found - possibly an embedding
2590 situation - see if we can locate it in sys.prefix
2591 */
2592 strncpy(modulepath,
2593 Py_GetExecPrefix(),
2594 sizeof(modulepath)/sizeof(modulepath[0]));
2595 if (modulepath[strlen(modulepath)-1] != '\\')
2596 strcat(modulepath, "\\");
2597 strncat(modulepath,
2598 szConsoleSpawn,
2599 (sizeof(modulepath)/sizeof(modulepath[0]))
2600 -strlen(modulepath));
2601 /* No where else to look - raise an easily identifiable
2602 error, rather than leaving Windows to report
2603 "file not found" - as the user is probably blissfully
2604 unaware this shim EXE is used, and it will confuse them.
2605 (well, it confused me for a while ;-)
2606 */
2607 if (stat(modulepath, &statinfo) != 0) {
2608 PyErr_Format(PyExc_RuntimeError,
2609 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002610 "for popen to work with your shell "
2611 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002612 szConsoleSpawn);
2613 return FALSE;
2614 }
2615 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002616 x = i + strlen(s3) + strlen(cmdstring) + 1 +
2617 strlen(modulepath) +
2618 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002619
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002620 s2 = (char *)_alloca(x);
2621 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002622 PyOS_snprintf(
2623 s2, x,
Mark Hammond08501372001-01-31 07:30:29 +00002624 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002625 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002626 s1,
2627 s3,
2628 cmdstring);
2629 }
2630 }
2631
2632 /* Could be an else here to try cmd.exe / command.com in the path
2633 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002634 else {
Tim Peters402d5982001-08-27 06:37:48 +00002635 PyErr_SetString(PyExc_RuntimeError,
2636 "Cannot locate a COMSPEC environment variable to "
2637 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002638 return FALSE;
2639 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002640
2641 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2642 siStartInfo.cb = sizeof(STARTUPINFO);
2643 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2644 siStartInfo.hStdInput = hStdin;
2645 siStartInfo.hStdOutput = hStdout;
2646 siStartInfo.hStdError = hStderr;
2647 siStartInfo.wShowWindow = SW_HIDE;
2648
2649 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002650 s2,
2651 NULL,
2652 NULL,
2653 TRUE,
2654 CREATE_NEW_CONSOLE,
2655 NULL,
2656 NULL,
2657 &siStartInfo,
2658 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002659 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002660 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002661
Mark Hammondb37a3732000-08-14 04:47:33 +00002662 /* Return process handle */
2663 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002664 return TRUE;
2665 }
Tim Peters402d5982001-08-27 06:37:48 +00002666 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002667 return FALSE;
2668}
2669
2670/* The following code is based off of KB: Q190351 */
2671
2672static PyObject *
2673_PyPopen(char *cmdstring, int mode, int n)
2674{
2675 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2676 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002677 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002678
2679 SECURITY_ATTRIBUTES saAttr;
2680 BOOL fSuccess;
2681 int fd1, fd2, fd3;
2682 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002683 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002684 PyObject *f;
2685
2686 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2687 saAttr.bInheritHandle = TRUE;
2688 saAttr.lpSecurityDescriptor = NULL;
2689
2690 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2691 return win32_error("CreatePipe", NULL);
2692
2693 /* Create new output read handle and the input write handle. Set
2694 * the inheritance properties to FALSE. Otherwise, the child inherits
2695 * the these handles; resulting in non-closeable handles to the pipes
2696 * being created. */
2697 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002698 GetCurrentProcess(), &hChildStdinWrDup, 0,
2699 FALSE,
2700 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002701 if (!fSuccess)
2702 return win32_error("DuplicateHandle", NULL);
2703
2704 /* Close the inheritable version of ChildStdin
2705 that we're using. */
2706 CloseHandle(hChildStdinWr);
2707
2708 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2709 return win32_error("CreatePipe", NULL);
2710
2711 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002712 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2713 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002714 if (!fSuccess)
2715 return win32_error("DuplicateHandle", NULL);
2716
2717 /* Close the inheritable version of ChildStdout
2718 that we're using. */
2719 CloseHandle(hChildStdoutRd);
2720
2721 if (n != POPEN_4) {
2722 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2723 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002724 fSuccess = DuplicateHandle(GetCurrentProcess(),
2725 hChildStderrRd,
2726 GetCurrentProcess(),
2727 &hChildStderrRdDup, 0,
2728 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002729 if (!fSuccess)
2730 return win32_error("DuplicateHandle", NULL);
2731 /* Close the inheritable version of ChildStdErr that we're using. */
2732 CloseHandle(hChildStderrRd);
2733 }
2734
2735 switch (n) {
2736 case POPEN_1:
2737 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2738 case _O_WRONLY | _O_TEXT:
2739 /* Case for writing to child Stdin in text mode. */
2740 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2741 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002742 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002743 PyFile_SetBufSize(f, 0);
2744 /* We don't care about these pipes anymore, so close them. */
2745 CloseHandle(hChildStdoutRdDup);
2746 CloseHandle(hChildStderrRdDup);
2747 break;
2748
2749 case _O_RDONLY | _O_TEXT:
2750 /* Case for reading from child Stdout in text mode. */
2751 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2752 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002753 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002754 PyFile_SetBufSize(f, 0);
2755 /* We don't care about these pipes anymore, so close them. */
2756 CloseHandle(hChildStdinWrDup);
2757 CloseHandle(hChildStderrRdDup);
2758 break;
2759
2760 case _O_RDONLY | _O_BINARY:
2761 /* Case for readinig from child Stdout in binary mode. */
2762 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2763 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002764 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002765 PyFile_SetBufSize(f, 0);
2766 /* We don't care about these pipes anymore, so close them. */
2767 CloseHandle(hChildStdinWrDup);
2768 CloseHandle(hChildStderrRdDup);
2769 break;
2770
2771 case _O_WRONLY | _O_BINARY:
2772 /* Case for writing to child Stdin in binary mode. */
2773 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2774 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002775 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002776 PyFile_SetBufSize(f, 0);
2777 /* We don't care about these pipes anymore, so close them. */
2778 CloseHandle(hChildStdoutRdDup);
2779 CloseHandle(hChildStderrRdDup);
2780 break;
2781 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002782 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002783 break;
2784
2785 case POPEN_2:
2786 case POPEN_4:
2787 {
2788 char *m1, *m2;
2789 PyObject *p1, *p2;
2790
2791 if (mode && _O_TEXT) {
2792 m1 = "r";
2793 m2 = "w";
2794 } else {
2795 m1 = "rb";
2796 m2 = "wb";
2797 }
2798
2799 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2800 f1 = _fdopen(fd1, m2);
2801 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2802 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002803 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002804 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002805 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002806 PyFile_SetBufSize(p2, 0);
2807
2808 if (n != 4)
2809 CloseHandle(hChildStderrRdDup);
2810
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002811 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002812 Py_XDECREF(p1);
2813 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002814 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002815 break;
2816 }
2817
2818 case POPEN_3:
2819 {
2820 char *m1, *m2;
2821 PyObject *p1, *p2, *p3;
2822
2823 if (mode && _O_TEXT) {
2824 m1 = "r";
2825 m2 = "w";
2826 } else {
2827 m1 = "rb";
2828 m2 = "wb";
2829 }
2830
2831 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2832 f1 = _fdopen(fd1, m2);
2833 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2834 f2 = _fdopen(fd2, m1);
2835 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2836 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002837 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002838 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2839 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002840 PyFile_SetBufSize(p1, 0);
2841 PyFile_SetBufSize(p2, 0);
2842 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002843 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002844 Py_XDECREF(p1);
2845 Py_XDECREF(p2);
2846 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002847 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002848 break;
2849 }
2850 }
2851
2852 if (n == POPEN_4) {
2853 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002854 hChildStdinRd,
2855 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002856 hChildStdoutWr,
2857 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002858 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002859 }
2860 else {
2861 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002862 hChildStdinRd,
2863 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002864 hChildStderrWr,
2865 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002866 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002867 }
2868
Mark Hammondb37a3732000-08-14 04:47:33 +00002869 /*
2870 * Insert the files we've created into the process dictionary
2871 * all referencing the list with the process handle and the
2872 * initial number of files (see description below in _PyPclose).
2873 * Since if _PyPclose later tried to wait on a process when all
2874 * handles weren't closed, it could create a deadlock with the
2875 * child, we spend some energy here to try to ensure that we
2876 * either insert all file handles into the dictionary or none
2877 * at all. It's a little clumsy with the various popen modes
2878 * and variable number of files involved.
2879 */
2880 if (!_PyPopenProcs) {
2881 _PyPopenProcs = PyDict_New();
2882 }
2883
2884 if (_PyPopenProcs) {
2885 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2886 int ins_rc[3];
2887
2888 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2889 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2890
2891 procObj = PyList_New(2);
2892 hProcessObj = PyLong_FromVoidPtr(hProcess);
2893 intObj = PyInt_FromLong(file_count);
2894
2895 if (procObj && hProcessObj && intObj) {
2896 PyList_SetItem(procObj,0,hProcessObj);
2897 PyList_SetItem(procObj,1,intObj);
2898
2899 fileObj[0] = PyLong_FromVoidPtr(f1);
2900 if (fileObj[0]) {
2901 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2902 fileObj[0],
2903 procObj);
2904 }
2905 if (file_count >= 2) {
2906 fileObj[1] = PyLong_FromVoidPtr(f2);
2907 if (fileObj[1]) {
2908 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2909 fileObj[1],
2910 procObj);
2911 }
2912 }
2913 if (file_count >= 3) {
2914 fileObj[2] = PyLong_FromVoidPtr(f3);
2915 if (fileObj[2]) {
2916 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2917 fileObj[2],
2918 procObj);
2919 }
2920 }
2921
2922 if (ins_rc[0] < 0 || !fileObj[0] ||
2923 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2924 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2925 /* Something failed - remove any dictionary
2926 * entries that did make it.
2927 */
2928 if (!ins_rc[0] && fileObj[0]) {
2929 PyDict_DelItem(_PyPopenProcs,
2930 fileObj[0]);
2931 }
2932 if (!ins_rc[1] && fileObj[1]) {
2933 PyDict_DelItem(_PyPopenProcs,
2934 fileObj[1]);
2935 }
2936 if (!ins_rc[2] && fileObj[2]) {
2937 PyDict_DelItem(_PyPopenProcs,
2938 fileObj[2]);
2939 }
2940 }
2941 }
2942
2943 /*
2944 * Clean up our localized references for the dictionary keys
2945 * and value since PyDict_SetItem will Py_INCREF any copies
2946 * that got placed in the dictionary.
2947 */
2948 Py_XDECREF(procObj);
2949 Py_XDECREF(fileObj[0]);
2950 Py_XDECREF(fileObj[1]);
2951 Py_XDECREF(fileObj[2]);
2952 }
2953
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002954 /* Child is launched. Close the parents copy of those pipe
2955 * handles that only the child should have open. You need to
2956 * make sure that no handles to the write end of the output pipe
2957 * are maintained in this process or else the pipe will not close
2958 * when the child process exits and the ReadFile will hang. */
2959
2960 if (!CloseHandle(hChildStdinRd))
2961 return win32_error("CloseHandle", NULL);
2962
2963 if (!CloseHandle(hChildStdoutWr))
2964 return win32_error("CloseHandle", NULL);
2965
2966 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2967 return win32_error("CloseHandle", NULL);
2968
2969 return f;
2970}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002971
2972/*
2973 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2974 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002975 *
2976 * This function uses the _PyPopenProcs dictionary in order to map the
2977 * input file pointer to information about the process that was
2978 * originally created by the popen* call that created the file pointer.
2979 * The dictionary uses the file pointer as a key (with one entry
2980 * inserted for each file returned by the original popen* call) and a
2981 * single list object as the value for all files from a single call.
2982 * The list object contains the Win32 process handle at [0], and a file
2983 * count at [1], which is initialized to the total number of file
2984 * handles using that list.
2985 *
2986 * This function closes whichever handle it is passed, and decrements
2987 * the file count in the dictionary for the process handle pointed to
2988 * by this file. On the last close (when the file count reaches zero),
2989 * this function will wait for the child process and then return its
2990 * exit code as the result of the close() operation. This permits the
2991 * files to be closed in any order - it is always the close() of the
2992 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002993 */
Tim Peters736aa322000-09-01 06:51:24 +00002994
2995 /* RED_FLAG 31-Aug-2000 Tim
2996 * This is always called (today!) between a pair of
2997 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2998 * macros. So the thread running this has no valid thread state, as
2999 * far as Python is concerned. However, this calls some Python API
3000 * functions that cannot be called safely without a valid thread
3001 * state, in particular PyDict_GetItem.
3002 * As a temporary hack (although it may last for years ...), we
3003 * *rely* on not having a valid thread state in this function, in
3004 * order to create our own "from scratch".
3005 * This will deadlock if _PyPclose is ever called by a thread
3006 * holding the global lock.
3007 */
3008
Fredrik Lundh56055a42000-07-23 19:47:12 +00003009static int _PyPclose(FILE *file)
3010{
Fredrik Lundh20318932000-07-26 17:29:12 +00003011 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003012 DWORD exit_code;
3013 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003014 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3015 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003016#ifdef WITH_THREAD
3017 PyInterpreterState* pInterpreterState;
3018 PyThreadState* pThreadState;
3019#endif
3020
Fredrik Lundh20318932000-07-26 17:29:12 +00003021 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003022 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003023 */
3024 result = fclose(file);
3025
Tim Peters736aa322000-09-01 06:51:24 +00003026#ifdef WITH_THREAD
3027 /* Bootstrap a valid thread state into existence. */
3028 pInterpreterState = PyInterpreterState_New();
3029 if (!pInterpreterState) {
3030 /* Well, we're hosed now! We don't have a thread
3031 * state, so can't call a nice error routine, or raise
3032 * an exception. Just die.
3033 */
3034 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003035 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003036 return -1; /* unreachable */
3037 }
3038 pThreadState = PyThreadState_New(pInterpreterState);
3039 if (!pThreadState) {
3040 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003041 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003042 return -1; /* unreachable */
3043 }
3044 /* Grab the global lock. Note that this will deadlock if the
3045 * current thread already has the lock! (see RED_FLAG comments
3046 * before this function)
3047 */
3048 PyEval_RestoreThread(pThreadState);
3049#endif
3050
Fredrik Lundh56055a42000-07-23 19:47:12 +00003051 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003052 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3053 (procObj = PyDict_GetItem(_PyPopenProcs,
3054 fileObj)) != NULL &&
3055 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3056 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3057
3058 hProcess = PyLong_AsVoidPtr(hProcessObj);
3059 file_count = PyInt_AsLong(intObj);
3060
3061 if (file_count > 1) {
3062 /* Still other files referencing process */
3063 file_count--;
3064 PyList_SetItem(procObj,1,
3065 PyInt_FromLong(file_count));
3066 } else {
3067 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003068 if (result != EOF &&
3069 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3070 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003071 /* Possible truncation here in 16-bit environments, but
3072 * real exit codes are just the lower byte in any event.
3073 */
3074 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003075 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003076 /* Indicate failure - this will cause the file object
3077 * to raise an I/O error and translate the last Win32
3078 * error code from errno. We do have a problem with
3079 * last errors that overlap the normal errno table,
3080 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003081 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003082 if (result != EOF) {
3083 /* If the error wasn't from the fclose(), then
3084 * set errno for the file object error handling.
3085 */
3086 errno = GetLastError();
3087 }
3088 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003089 }
3090
3091 /* Free up the native handle at this point */
3092 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003093 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003094
Mark Hammondb37a3732000-08-14 04:47:33 +00003095 /* Remove this file pointer from dictionary */
3096 PyDict_DelItem(_PyPopenProcs, fileObj);
3097
3098 if (PyDict_Size(_PyPopenProcs) == 0) {
3099 Py_DECREF(_PyPopenProcs);
3100 _PyPopenProcs = NULL;
3101 }
3102
3103 } /* if object retrieval ok */
3104
3105 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003106 } /* if _PyPopenProcs */
3107
Tim Peters736aa322000-09-01 06:51:24 +00003108#ifdef WITH_THREAD
3109 /* Tear down the thread & interpreter states.
3110 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003111 * call the thread clear & delete functions, and indeed insist on
3112 * doing that themselves. The lock must be held during the clear, but
3113 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003114 */
3115 PyInterpreterState_Clear(pInterpreterState);
3116 PyEval_ReleaseThread(pThreadState);
3117 PyInterpreterState_Delete(pInterpreterState);
3118#endif
3119
Fredrik Lundh56055a42000-07-23 19:47:12 +00003120 return result;
3121}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003122
3123#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003125posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003126{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003127 char *name;
3128 char *mode = "r";
3129 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003130 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003131 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003132 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003133 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003134 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003135 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003136 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003137 if (fp == NULL)
3138 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003139 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003140 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003141 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003142 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003143}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003144#endif
3145
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003146#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003148
Guido van Rossumb6775db1994-08-01 11:34:53 +00003149#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003150static char posix_setuid__doc__[] =
3151"setuid(uid) -> None\n\
3152Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003154posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003155{
3156 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003157 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003158 return NULL;
3159 if (setuid(uid) < 0)
3160 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003161 Py_INCREF(Py_None);
3162 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003163}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003164#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003165
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003166
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003167#ifdef HAVE_SETEUID
3168static char posix_seteuid__doc__[] =
3169"seteuid(uid) -> None\n\
3170Set the current process's effective user id.";
3171static PyObject *
3172posix_seteuid (PyObject *self, PyObject *args)
3173{
3174 int euid;
3175 if (!PyArg_ParseTuple(args, "i", &euid)) {
3176 return NULL;
3177 } else if (seteuid(euid) < 0) {
3178 return posix_error();
3179 } else {
3180 Py_INCREF(Py_None);
3181 return Py_None;
3182 }
3183}
3184#endif /* HAVE_SETEUID */
3185
3186#ifdef HAVE_SETEGID
3187static char posix_setegid__doc__[] =
3188"setegid(gid) -> None\n\
3189Set the current process's effective group id.";
3190static PyObject *
3191posix_setegid (PyObject *self, PyObject *args)
3192{
3193 int egid;
3194 if (!PyArg_ParseTuple(args, "i", &egid)) {
3195 return NULL;
3196 } else if (setegid(egid) < 0) {
3197 return posix_error();
3198 } else {
3199 Py_INCREF(Py_None);
3200 return Py_None;
3201 }
3202}
3203#endif /* HAVE_SETEGID */
3204
3205#ifdef HAVE_SETREUID
3206static char posix_setreuid__doc__[] =
3207"seteuid(ruid, euid) -> None\n\
3208Set the current process's real and effective user ids.";
3209static PyObject *
3210posix_setreuid (PyObject *self, PyObject *args)
3211{
3212 int ruid, euid;
3213 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3214 return NULL;
3215 } else if (setreuid(ruid, euid) < 0) {
3216 return posix_error();
3217 } else {
3218 Py_INCREF(Py_None);
3219 return Py_None;
3220 }
3221}
3222#endif /* HAVE_SETREUID */
3223
3224#ifdef HAVE_SETREGID
3225static char posix_setregid__doc__[] =
3226"setegid(rgid, egid) -> None\n\
3227Set the current process's real and effective group ids.";
3228static PyObject *
3229posix_setregid (PyObject *self, PyObject *args)
3230{
3231 int rgid, egid;
3232 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3233 return NULL;
3234 } else if (setregid(rgid, egid) < 0) {
3235 return posix_error();
3236 } else {
3237 Py_INCREF(Py_None);
3238 return Py_None;
3239 }
3240}
3241#endif /* HAVE_SETREGID */
3242
Guido van Rossumb6775db1994-08-01 11:34:53 +00003243#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003244static char posix_setgid__doc__[] =
3245"setgid(gid) -> None\n\
3246Set the current process's group id.";
3247
Barry Warsaw53699e91996-12-10 23:23:01 +00003248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003249posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003250{
3251 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003252 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003253 return NULL;
3254 if (setgid(gid) < 0)
3255 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003256 Py_INCREF(Py_None);
3257 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003258}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003259#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003260
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003261#ifdef HAVE_SETGROUPS
3262static char posix_setgroups__doc__[] =
3263"setgroups(list) -> None\n\
3264Set the groups of the current process to list.";
3265
3266static PyObject *
3267posix_setgroups(PyObject *self, PyObject *args)
3268{
3269 PyObject *groups;
3270 int i, len;
3271 gid_t grouplist[MAX_GROUPS];
3272
3273 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3274 return NULL;
3275 if (!PySequence_Check(groups)) {
3276 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3277 return NULL;
3278 }
3279 len = PySequence_Size(groups);
3280 if (len > MAX_GROUPS) {
3281 PyErr_SetString(PyExc_ValueError, "too many groups");
3282 return NULL;
3283 }
3284 for(i = 0; i < len; i++) {
3285 PyObject *elem;
3286 elem = PySequence_GetItem(groups, i);
3287 if (!elem)
3288 return NULL;
3289 if (!PyInt_Check(elem)) {
3290 PyErr_SetString(PyExc_TypeError,
3291 "groups must be integers");
3292 Py_DECREF(elem);
3293 return NULL;
3294 }
3295 /* XXX: check that value fits into gid_t. */
3296 grouplist[i] = PyInt_AsLong(elem);
3297 Py_DECREF(elem);
3298 }
3299
3300 if (setgroups(len, grouplist) < 0)
3301 return posix_error();
3302 Py_INCREF(Py_None);
3303 return Py_None;
3304}
3305#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003306
Guido van Rossumb6775db1994-08-01 11:34:53 +00003307#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003308static char posix_waitpid__doc__[] =
3309"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003310Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003311
Barry Warsaw53699e91996-12-10 23:23:01 +00003312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003313posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003314{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003315 int pid, options;
3316#ifdef UNION_WAIT
3317 union wait status;
3318#define status_i (status.w_status)
3319#else
3320 int status;
3321#define status_i status
3322#endif
3323 status_i = 0;
3324
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003325 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003326 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003327 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003328#ifdef NeXT
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003329 pid = wait4(pid, &status, options, NULL);
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003330#else
3331 pid = waitpid(pid, &status, options);
3332#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003333 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003334 if (pid == -1)
3335 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003336 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003337 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003338}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003339#endif /* HAVE_WAITPID */
Guido van Rossum21803b81992-08-09 12:55:27 +00003340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003341
Guido van Rossumad0ee831995-03-01 10:34:45 +00003342#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003343static char posix_wait__doc__[] =
3344"wait() -> (pid, status)\n\
3345Wait for completion of a child process.";
3346
Barry Warsaw53699e91996-12-10 23:23:01 +00003347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003348posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003349{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003350 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003351#ifdef UNION_WAIT
3352 union wait status;
3353#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003354#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003355 int status;
3356#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003357#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003358 if (!PyArg_ParseTuple(args, ":wait"))
3359 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003360 status_i = 0;
3361 Py_BEGIN_ALLOW_THREADS
3362 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003363 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003364 if (pid == -1)
3365 return posix_error();
3366 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003367 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003368#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003369}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003370#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003371
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003372
3373static char posix_lstat__doc__[] =
3374"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3375Like stat(path), but do not follow symbolic links.";
3376
Barry Warsaw53699e91996-12-10 23:23:01 +00003377static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003378posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003379{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003380#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003381 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003382#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003383 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003384#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003385}
3386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003387
Guido van Rossumb6775db1994-08-01 11:34:53 +00003388#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003389static char posix_readlink__doc__[] =
3390"readlink(path) -> path\n\
3391Return a string representing the path to which the symbolic link points.";
3392
Barry Warsaw53699e91996-12-10 23:23:01 +00003393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003394posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003395{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003396 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003397 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003398 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003399 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003400 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003401 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003402 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003403 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003404 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003405 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003406 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003407}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003408#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003410
Guido van Rossumb6775db1994-08-01 11:34:53 +00003411#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003412static char posix_symlink__doc__[] =
3413"symlink(src, dst) -> None\n\
3414Create a symbolic link.";
3415
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003417posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003418{
Mark Hammondef8b6542001-05-13 08:04:26 +00003419 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003420}
3421#endif /* HAVE_SYMLINK */
3422
3423
3424#ifdef HAVE_TIMES
3425#ifndef HZ
3426#define HZ 60 /* Universal constant :-) */
3427#endif /* HZ */
3428
Guido van Rossumd48f2521997-12-05 22:19:34 +00003429#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3430static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003431system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003432{
3433 ULONG value = 0;
3434
3435 Py_BEGIN_ALLOW_THREADS
3436 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3437 Py_END_ALLOW_THREADS
3438
3439 return value;
3440}
3441
3442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003443posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003444{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003445 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003446 return NULL;
3447
3448 /* Currently Only Uptime is Provided -- Others Later */
3449 return Py_BuildValue("ddddd",
3450 (double)0 /* t.tms_utime / HZ */,
3451 (double)0 /* t.tms_stime / HZ */,
3452 (double)0 /* t.tms_cutime / HZ */,
3453 (double)0 /* t.tms_cstime / HZ */,
3454 (double)system_uptime() / 1000);
3455}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003456#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003458posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003459{
3460 struct tms t;
3461 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003462 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003463 return NULL;
3464 errno = 0;
3465 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003466 if (c == (clock_t) -1)
3467 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003468 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003469 (double)t.tms_utime / HZ,
3470 (double)t.tms_stime / HZ,
3471 (double)t.tms_cutime / HZ,
3472 (double)t.tms_cstime / HZ,
3473 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003474}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003475#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003476#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003477
3478
Guido van Rossum87755a21996-09-07 00:59:43 +00003479#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003480#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003481static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003482posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003483{
3484 FILETIME create, exit, kernel, user;
3485 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003486 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003487 return NULL;
3488 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003489 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3490 /* The fields of a FILETIME structure are the hi and lo part
3491 of a 64-bit value expressed in 100 nanosecond units.
3492 1e7 is one second in such units; 1e-7 the inverse.
3493 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3494 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003495 return Py_BuildValue(
3496 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003497 (double)(kernel.dwHighDateTime*429.4967296 +
3498 kernel.dwLowDateTime*1e-7),
3499 (double)(user.dwHighDateTime*429.4967296 +
3500 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003501 (double)0,
3502 (double)0,
3503 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003504}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003505#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003506
3507#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003508static char posix_times__doc__[] =
3509"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3510Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003511#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003512
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003513
Guido van Rossumb6775db1994-08-01 11:34:53 +00003514#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003515static char posix_setsid__doc__[] =
3516"setsid() -> None\n\
3517Call the system call setsid().";
3518
Barry Warsaw53699e91996-12-10 23:23:01 +00003519static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003520posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003521{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003522 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003523 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003524 if (setsid() < 0)
3525 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003526 Py_INCREF(Py_None);
3527 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003528}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003529#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003530
Guido van Rossumb6775db1994-08-01 11:34:53 +00003531#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003532static char posix_setpgid__doc__[] =
3533"setpgid(pid, pgrp) -> None\n\
3534Call the system call setpgid().";
3535
Barry Warsaw53699e91996-12-10 23:23:01 +00003536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003537posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003538{
3539 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003540 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003541 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003542 if (setpgid(pid, pgrp) < 0)
3543 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003544 Py_INCREF(Py_None);
3545 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003546}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003547#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003548
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003549
Guido van Rossumb6775db1994-08-01 11:34:53 +00003550#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003551static char posix_tcgetpgrp__doc__[] =
3552"tcgetpgrp(fd) -> pgid\n\
3553Return the process group associated with the terminal given by a fd.";
3554
Barry Warsaw53699e91996-12-10 23:23:01 +00003555static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003556posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003557{
3558 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003559 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003560 return NULL;
3561 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003562 if (pgid < 0)
3563 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003564 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003565}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003566#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003568
Guido van Rossumb6775db1994-08-01 11:34:53 +00003569#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003570static char posix_tcsetpgrp__doc__[] =
3571"tcsetpgrp(fd, pgid) -> None\n\
3572Set the process group associated with the terminal given by a fd.";
3573
Barry Warsaw53699e91996-12-10 23:23:01 +00003574static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003575posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003576{
3577 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003578 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003579 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003580 if (tcsetpgrp(fd, pgid) < 0)
3581 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003582 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003583 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003584}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003585#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003586
Guido van Rossum687dd131993-05-17 08:34:16 +00003587/* Functions acting on file descriptors */
3588
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003589static char posix_open__doc__[] =
3590"open(filename, flag [, mode=0777]) -> fd\n\
3591Open a file (for low level IO).";
3592
Barry Warsaw53699e91996-12-10 23:23:01 +00003593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003594posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003595{
Mark Hammondef8b6542001-05-13 08:04:26 +00003596 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003597 int flag;
3598 int mode = 0777;
3599 int fd;
Mark Hammondef8b6542001-05-13 08:04:26 +00003600 if (!PyArg_ParseTuple(args, "eti|i",
3601 Py_FileSystemDefaultEncoding, &file,
3602 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003603 return NULL;
3604
Barry Warsaw53699e91996-12-10 23:23:01 +00003605 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003606 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003607 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003608 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003609 return posix_error_with_allocated_filename(file);
3610 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003611 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003612}
3613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003614
3615static char posix_close__doc__[] =
3616"close(fd) -> None\n\
3617Close a file descriptor (for low level IO).";
3618
Barry Warsaw53699e91996-12-10 23:23:01 +00003619static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003620posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003621{
3622 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003623 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003624 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003625 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003626 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003627 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003628 if (res < 0)
3629 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003630 Py_INCREF(Py_None);
3631 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003632}
3633
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003634
3635static char posix_dup__doc__[] =
3636"dup(fd) -> fd2\n\
3637Return a duplicate of a file descriptor.";
3638
Barry Warsaw53699e91996-12-10 23:23:01 +00003639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003640posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003641{
3642 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003643 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003644 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003645 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003646 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003647 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003648 if (fd < 0)
3649 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003650 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003651}
3652
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003653
3654static char posix_dup2__doc__[] =
3655"dup2(fd, fd2) -> None\n\
3656Duplicate file descriptor.";
3657
Barry Warsaw53699e91996-12-10 23:23:01 +00003658static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003659posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003660{
3661 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003662 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003663 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003664 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003665 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003666 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003667 if (res < 0)
3668 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003669 Py_INCREF(Py_None);
3670 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003671}
3672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003673
3674static char posix_lseek__doc__[] =
3675"lseek(fd, pos, how) -> newpos\n\
3676Set the current position of a file descriptor.";
3677
Barry Warsaw53699e91996-12-10 23:23:01 +00003678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003679posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003680{
3681 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003682#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003683 LONG_LONG pos, res;
3684#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003685 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003686#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003687 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003688 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003689 return NULL;
3690#ifdef SEEK_SET
3691 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3692 switch (how) {
3693 case 0: how = SEEK_SET; break;
3694 case 1: how = SEEK_CUR; break;
3695 case 2: how = SEEK_END; break;
3696 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003697#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003698
3699#if !defined(HAVE_LARGEFILE_SUPPORT)
3700 pos = PyInt_AsLong(posobj);
3701#else
3702 pos = PyLong_Check(posobj) ?
3703 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3704#endif
3705 if (PyErr_Occurred())
3706 return NULL;
3707
Barry Warsaw53699e91996-12-10 23:23:01 +00003708 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003709#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003710 res = _lseeki64(fd, pos, how);
3711#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003712 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003713#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003714 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003715 if (res < 0)
3716 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003717
3718#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003719 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003720#else
3721 return PyLong_FromLongLong(res);
3722#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003723}
3724
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003725
3726static char posix_read__doc__[] =
3727"read(fd, buffersize) -> string\n\
3728Read a file descriptor.";
3729
Barry Warsaw53699e91996-12-10 23:23:01 +00003730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003731posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003732{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003733 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003734 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003735 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003736 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003737 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003738 if (buffer == NULL)
3739 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003740 Py_BEGIN_ALLOW_THREADS
3741 n = read(fd, PyString_AsString(buffer), size);
3742 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003743 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003744 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003745 return posix_error();
3746 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003747 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003748 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003749 return buffer;
3750}
3751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003752
3753static char posix_write__doc__[] =
3754"write(fd, string) -> byteswritten\n\
3755Write a string to a file descriptor.";
3756
Barry Warsaw53699e91996-12-10 23:23:01 +00003757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003758posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003759{
3760 int fd, size;
3761 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003762 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003763 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003764 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003765 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003766 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003767 if (size < 0)
3768 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003769 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003770}
3771
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003772
3773static char posix_fstat__doc__[]=
3774"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3775Like stat(), but for an open file descriptor.";
3776
Barry Warsaw53699e91996-12-10 23:23:01 +00003777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003778posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003779{
3780 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003781 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003782 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003783 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003784 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003785 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003786 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003787 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003788 if (res != 0)
3789 return posix_error();
Fred Drake699f3522000-06-29 21:12:41 +00003790
3791 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003792}
3793
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003794
3795static char posix_fdopen__doc__[] =
3796"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3797Return an open file object connected to a file descriptor.";
3798
Barry Warsaw53699e91996-12-10 23:23:01 +00003799static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003800posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003801{
Guido van Rossum687dd131993-05-17 08:34:16 +00003802 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003803 char *mode = "r";
3804 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003805 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003806 PyObject *f;
3807 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003808 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003809
Barry Warsaw53699e91996-12-10 23:23:01 +00003810 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003811 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003812 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003813 if (fp == NULL)
3814 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003815 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003816 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003817 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003818 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003819}
3820
Skip Montanaro1517d842000-07-19 14:34:14 +00003821static char posix_isatty__doc__[] =
3822"isatty(fd) -> Boolean\n\
3823Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003824connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003825
3826static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003827posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003828{
3829 int fd;
3830 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3831 return NULL;
3832 return Py_BuildValue("i", isatty(fd));
3833}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003834
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003835#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003836static char posix_pipe__doc__[] =
3837"pipe() -> (read_end, write_end)\n\
3838Create a pipe.";
3839
Barry Warsaw53699e91996-12-10 23:23:01 +00003840static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003841posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003842{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003843#if defined(PYOS_OS2)
3844 HFILE read, write;
3845 APIRET rc;
3846
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003847 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003848 return NULL;
3849
3850 Py_BEGIN_ALLOW_THREADS
3851 rc = DosCreatePipe( &read, &write, 4096);
3852 Py_END_ALLOW_THREADS
3853 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003854 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003855
3856 return Py_BuildValue("(ii)", read, write);
3857#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003858#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003859 int fds[2];
3860 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003861 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003862 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003863 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003864 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003865 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003866 if (res != 0)
3867 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003868 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003869#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003870 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003871 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003872 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003873 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003874 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003875 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003876 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003877 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003878 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003879 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003880 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3881 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003882 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003883#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003884#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003885}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003886#endif /* HAVE_PIPE */
3887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003888
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003889#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003890static char posix_mkfifo__doc__[] =
3891"mkfifo(file, [, mode=0666]) -> None\n\
3892Create a FIFO (a POSIX named pipe).";
3893
Barry Warsaw53699e91996-12-10 23:23:01 +00003894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003895posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003896{
3897 char *file;
3898 int mode = 0666;
3899 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003900 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003901 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003902 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003903 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003904 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003905 if (res < 0)
3906 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003907 Py_INCREF(Py_None);
3908 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003909}
3910#endif
3911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003912
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003913#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003914static char posix_ftruncate__doc__[] =
3915"ftruncate(fd, length) -> None\n\
3916Truncate a file to a specified length.";
3917
Barry Warsaw53699e91996-12-10 23:23:01 +00003918static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003919posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003920{
3921 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003922 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003923 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003924 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003925
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003926 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003927 return NULL;
3928
3929#if !defined(HAVE_LARGEFILE_SUPPORT)
3930 length = PyInt_AsLong(lenobj);
3931#else
3932 length = PyLong_Check(lenobj) ?
3933 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3934#endif
3935 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003936 return NULL;
3937
Barry Warsaw53699e91996-12-10 23:23:01 +00003938 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003939 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003940 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003941 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003942 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003943 return NULL;
3944 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003945 Py_INCREF(Py_None);
3946 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003947}
3948#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003949
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003950#ifdef NeXT
3951#define HAVE_PUTENV
3952/* Steve Spicklemire got this putenv from NeXTAnswers */
3953static int
3954putenv(char *newval)
3955{
3956 extern char **environ;
3957
3958 static int firstTime = 1;
3959 char **ep;
3960 char *cp;
3961 int esiz;
3962 char *np;
3963
3964 if (!(np = strchr(newval, '=')))
3965 return 1;
3966 *np = '\0';
3967
3968 /* look it up */
3969 for (ep=environ ; *ep ; ep++)
3970 {
3971 /* this should always be true... */
3972 if (cp = strchr(*ep, '='))
3973 {
3974 *cp = '\0';
3975 if (!strcmp(*ep, newval))
3976 {
3977 /* got it! */
3978 *cp = '=';
3979 break;
3980 }
3981 *cp = '=';
3982 }
3983 else
3984 {
3985 *np = '=';
3986 return 1;
3987 }
3988 }
3989
3990 *np = '=';
3991 if (*ep)
3992 {
3993 /* the string was already there:
3994 just replace it with the new one */
3995 *ep = newval;
3996 return 0;
3997 }
3998
3999 /* expand environ by one */
4000 for (esiz=2, ep=environ ; *ep ; ep++)
4001 esiz++;
4002 if (firstTime)
4003 {
4004 char **epp;
4005 char **newenv;
4006 if (!(newenv = malloc(esiz * sizeof(char *))))
4007 return 1;
4008
4009 for (ep=environ, epp=newenv ; *ep ;)
4010 *epp++ = *ep++;
4011 *epp++ = newval;
4012 *epp = (char *) 0;
4013 environ = newenv;
4014 }
4015 else
4016 {
4017 if (!(environ = realloc(environ, esiz * sizeof(char *))))
4018 return 1;
4019 environ[esiz - 2] = newval;
4020 environ[esiz - 1] = (char *) 0;
4021 firstTime = 0;
4022 }
4023
4024 return 0;
4025}
Guido van Rossumc6ef2041997-08-21 02:30:45 +00004026#endif /* NeXT */
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004028
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004029#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004030static char posix_putenv__doc__[] =
4031"putenv(key, value) -> None\n\
4032Change or add an environment variable.";
4033
Fred Drake762e2061999-08-26 17:23:54 +00004034/* Save putenv() parameters as values here, so we can collect them when they
4035 * get re-set with another call for the same key. */
4036static PyObject *posix_putenv_garbage;
4037
Barry Warsaw53699e91996-12-10 23:23:01 +00004038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004039posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004040{
4041 char *s1, *s2;
4042 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004043 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004044 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004045
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004046 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004047 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004048
4049#if defined(PYOS_OS2)
4050 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4051 APIRET rc;
4052
4053 if (strlen(s2) == 0) /* If New Value is an Empty String */
4054 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4055
4056 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4057 if (rc != NO_ERROR)
4058 return os2_error(rc);
4059
4060 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4061 APIRET rc;
4062
4063 if (strlen(s2) == 0) /* If New Value is an Empty String */
4064 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4065
4066 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4067 if (rc != NO_ERROR)
4068 return os2_error(rc);
4069 } else {
4070#endif
4071
Fred Drake762e2061999-08-26 17:23:54 +00004072 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004073 len = strlen(s1) + strlen(s2) + 2;
4074 /* len includes space for a trailing \0; the size arg to
4075 PyString_FromStringAndSize does not count that */
4076 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004077 if (newstr == NULL)
4078 return PyErr_NoMemory();
4079 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004080 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004081 if (putenv(new)) {
4082 posix_error();
4083 return NULL;
4084 }
Fred Drake762e2061999-08-26 17:23:54 +00004085 /* Install the first arg and newstr in posix_putenv_garbage;
4086 * this will cause previous value to be collected. This has to
4087 * happen after the real putenv() call because the old value
4088 * was still accessible until then. */
4089 if (PyDict_SetItem(posix_putenv_garbage,
4090 PyTuple_GET_ITEM(args, 0), newstr)) {
4091 /* really not much we can do; just leak */
4092 PyErr_Clear();
4093 }
4094 else {
4095 Py_DECREF(newstr);
4096 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004097
4098#if defined(PYOS_OS2)
4099 }
4100#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004101 Py_INCREF(Py_None);
4102 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004103}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004104#endif /* putenv */
4105
Guido van Rossumc524d952001-10-19 01:31:59 +00004106#ifdef HAVE_UNSETENV
4107static char posix_unsetenv__doc__[] =
4108"unsetenv(key) -> None\n\
4109Delete an environment variable.";
4110
4111static PyObject *
4112posix_unsetenv(PyObject *self, PyObject *args)
4113{
4114 char *s1;
4115
4116 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4117 return NULL;
4118
4119 unsetenv(s1);
4120
4121 /* Remove the key from posix_putenv_garbage;
4122 * this will cause it to be collected. This has to
4123 * happen after the real unsetenv() call because the
4124 * old value was still accessible until then.
4125 */
4126 if (PyDict_DelItem(posix_putenv_garbage,
4127 PyTuple_GET_ITEM(args, 0))) {
4128 /* really not much we can do; just leak */
4129 PyErr_Clear();
4130 }
4131
4132 Py_INCREF(Py_None);
4133 return Py_None;
4134}
4135#endif /* unsetenv */
4136
Guido van Rossumb6a47161997-09-15 22:54:34 +00004137#ifdef HAVE_STRERROR
4138static char posix_strerror__doc__[] =
4139"strerror(code) -> string\n\
4140Translate an error code to a message string.";
4141
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004143posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004144{
4145 int code;
4146 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004147 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004148 return NULL;
4149 message = strerror(code);
4150 if (message == NULL) {
4151 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004152 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004153 return NULL;
4154 }
4155 return PyString_FromString(message);
4156}
4157#endif /* strerror */
4158
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004159
Guido van Rossumc9641791998-08-04 15:26:23 +00004160#ifdef HAVE_SYS_WAIT_H
4161
4162#ifdef WIFSTOPPED
4163static char posix_WIFSTOPPED__doc__[] =
4164"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004165Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004166
4167static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004168posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004169{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004170#ifdef UNION_WAIT
4171 union wait status;
4172#define status_i (status.w_status)
4173#else
4174 int status;
4175#define status_i status
4176#endif
4177 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004178
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004179 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004180 {
4181 return NULL;
4182 }
4183
4184 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004185#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004186}
4187#endif /* WIFSTOPPED */
4188
4189#ifdef WIFSIGNALED
4190static char posix_WIFSIGNALED__doc__[] =
4191"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004192Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004193
4194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004195posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004196{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004197#ifdef UNION_WAIT
4198 union wait status;
4199#define status_i (status.w_status)
4200#else
4201 int status;
4202#define status_i status
4203#endif
4204 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004205
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004206 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004207 {
4208 return NULL;
4209 }
4210
4211 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004212#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004213}
4214#endif /* WIFSIGNALED */
4215
4216#ifdef WIFEXITED
4217static char posix_WIFEXITED__doc__[] =
4218"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004219Return true if the process returning 'status' exited using the exit()\n\
4220system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004221
4222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004223posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004224{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004225#ifdef UNION_WAIT
4226 union wait status;
4227#define status_i (status.w_status)
4228#else
4229 int status;
4230#define status_i status
4231#endif
4232 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004233
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004234 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004235 {
4236 return NULL;
4237 }
4238
4239 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004240#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004241}
4242#endif /* WIFEXITED */
4243
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004244#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004245static char posix_WEXITSTATUS__doc__[] =
4246"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004247Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004248
4249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004250posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004251{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004252#ifdef UNION_WAIT
4253 union wait status;
4254#define status_i (status.w_status)
4255#else
4256 int status;
4257#define status_i status
4258#endif
4259 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004260
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004261 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004262 {
4263 return NULL;
4264 }
4265
4266 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004267#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004268}
4269#endif /* WEXITSTATUS */
4270
4271#ifdef WTERMSIG
4272static char posix_WTERMSIG__doc__[] =
4273"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004274Return the signal that terminated the process that provided the 'status'\n\
4275value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004276
4277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004278posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004279{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004280#ifdef UNION_WAIT
4281 union wait status;
4282#define status_i (status.w_status)
4283#else
4284 int status;
4285#define status_i status
4286#endif
4287 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004288
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004289 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004290 {
4291 return NULL;
4292 }
4293
4294 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004295#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004296}
4297#endif /* WTERMSIG */
4298
4299#ifdef WSTOPSIG
4300static char posix_WSTOPSIG__doc__[] =
4301"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004302Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004303
4304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004305posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004306{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004307#ifdef UNION_WAIT
4308 union wait status;
4309#define status_i (status.w_status)
4310#else
4311 int status;
4312#define status_i status
4313#endif
4314 status_i = 0;
Guido van Rossumc9641791998-08-04 15:26:23 +00004315
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004316 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004317 {
4318 return NULL;
4319 }
4320
4321 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004322#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004323}
4324#endif /* WSTOPSIG */
4325
4326#endif /* HAVE_SYS_WAIT_H */
4327
4328
Guido van Rossum94f6f721999-01-06 18:42:14 +00004329#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004330#ifdef _SCO_DS
4331/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4332 needed definitions in sys/statvfs.h */
4333#define _SVID3
4334#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004335#include <sys/statvfs.h>
4336
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004337static PyObject*
4338_pystatvfs_fromstructstatvfs(struct statvfs st) {
4339 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4340 if (v == NULL)
4341 return NULL;
4342
4343#if !defined(HAVE_LARGEFILE_SUPPORT)
4344 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4345 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4346 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4347 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4348 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4349 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4350 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4351 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4352 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4353 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4354#else
4355 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4356 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4357 PyStructSequence_SET_ITEM(v, 2,
4358 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
4359 PyStructSequence_SET_ITEM(v, 3,
4360 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4361 PyStructSequence_SET_ITEM(v, 4,
4362 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
4363 PyStructSequence_SET_ITEM(v, 5,
4364 PyLong_FromLongLong((LONG_LONG) st.f_files));
4365 PyStructSequence_SET_ITEM(v, 6,
4366 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
4367 PyStructSequence_SET_ITEM(v, 7,
4368 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4369 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4370 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4371#endif
4372
4373 return v;
4374}
4375
Guido van Rossum94f6f721999-01-06 18:42:14 +00004376static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004377"fstatvfs(fd) -> \n\
4378 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004379Perform an fstatvfs system call on the given fd.";
4380
4381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004382posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004383{
4384 int fd, res;
4385 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004386
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004387 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004388 return NULL;
4389 Py_BEGIN_ALLOW_THREADS
4390 res = fstatvfs(fd, &st);
4391 Py_END_ALLOW_THREADS
4392 if (res != 0)
4393 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004394
4395 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004396}
4397#endif /* HAVE_FSTATVFS */
4398
4399
4400#if defined(HAVE_STATVFS)
4401#include <sys/statvfs.h>
4402
4403static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004404"statvfs(path) -> \n\
4405 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004406Perform a statvfs system call on the given path.";
4407
4408static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004409posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004410{
4411 char *path;
4412 int res;
4413 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004414 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004415 return NULL;
4416 Py_BEGIN_ALLOW_THREADS
4417 res = statvfs(path, &st);
4418 Py_END_ALLOW_THREADS
4419 if (res != 0)
4420 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004421
4422 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004423}
4424#endif /* HAVE_STATVFS */
4425
4426
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004427#ifdef HAVE_TEMPNAM
4428static char posix_tempnam__doc__[] = "\
4429tempnam([dir[, prefix]]) -> string\n\
4430Return a unique name for a temporary file.\n\
4431The directory and a short may be specified as strings; they may be omitted\n\
4432or None if not needed.";
4433
4434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004435posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004436{
4437 PyObject *result = NULL;
4438 char *dir = NULL;
4439 char *pfx = NULL;
4440 char *name;
4441
4442 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4443 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004444
4445 if (PyErr_Warn(PyExc_RuntimeWarning,
4446 "tempnam is a potential security risk to your program") < 0)
4447 return NULL;
4448
Fred Drake78b71c22001-07-17 20:37:36 +00004449#ifdef MS_WIN32
4450 name = _tempnam(dir, pfx);
4451#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004452 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004453#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004454 if (name == NULL)
4455 return PyErr_NoMemory();
4456 result = PyString_FromString(name);
4457 free(name);
4458 return result;
4459}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004460#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004461
4462
4463#ifdef HAVE_TMPFILE
4464static char posix_tmpfile__doc__[] = "\
4465tmpfile() -> file object\n\
4466Create a temporary file with no directory entries.";
4467
4468static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004469posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004470{
4471 FILE *fp;
4472
4473 if (!PyArg_ParseTuple(args, ":tmpfile"))
4474 return NULL;
4475 fp = tmpfile();
4476 if (fp == NULL)
4477 return posix_error();
4478 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4479}
4480#endif
4481
4482
4483#ifdef HAVE_TMPNAM
4484static char posix_tmpnam__doc__[] = "\
4485tmpnam() -> string\n\
4486Return a unique name for a temporary file.";
4487
4488static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004489posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004490{
4491 char buffer[L_tmpnam];
4492 char *name;
4493
4494 if (!PyArg_ParseTuple(args, ":tmpnam"))
4495 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004496
4497 if (PyErr_Warn(PyExc_RuntimeWarning,
4498 "tmpnam is a potential security risk to your program") < 0)
4499 return NULL;
4500
Greg Wardb48bc172000-03-01 21:51:56 +00004501#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004502 name = tmpnam_r(buffer);
4503#else
4504 name = tmpnam(buffer);
4505#endif
4506 if (name == NULL) {
4507 PyErr_SetObject(PyExc_OSError,
4508 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004509#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004510 "unexpected NULL from tmpnam_r"
4511#else
4512 "unexpected NULL from tmpnam"
4513#endif
4514 ));
4515 return NULL;
4516 }
4517 return PyString_FromString(buffer);
4518}
4519#endif
4520
4521
Fred Drakec9680921999-12-13 16:37:25 +00004522/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4523 * It maps strings representing configuration variable names to
4524 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004525 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004526 * rarely-used constants. There are three separate tables that use
4527 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004528 *
4529 * This code is always included, even if none of the interfaces that
4530 * need it are included. The #if hackery needed to avoid it would be
4531 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004532 */
4533struct constdef {
4534 char *name;
4535 long value;
4536};
4537
Fred Drake12c6e2d1999-12-14 21:25:03 +00004538static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004539conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4540 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004541{
4542 if (PyInt_Check(arg)) {
4543 *valuep = PyInt_AS_LONG(arg);
4544 return 1;
4545 }
4546 if (PyString_Check(arg)) {
4547 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004548 size_t lo = 0;
4549 size_t mid;
4550 size_t hi = tablesize;
4551 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004552 char *confname = PyString_AS_STRING(arg);
4553 while (lo < hi) {
4554 mid = (lo + hi) / 2;
4555 cmp = strcmp(confname, table[mid].name);
4556 if (cmp < 0)
4557 hi = mid;
4558 else if (cmp > 0)
4559 lo = mid + 1;
4560 else {
4561 *valuep = table[mid].value;
4562 return 1;
4563 }
4564 }
4565 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4566 }
4567 else
4568 PyErr_SetString(PyExc_TypeError,
4569 "configuration names must be strings or integers");
4570 return 0;
4571}
4572
4573
4574#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4575static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004576#ifdef _PC_ABI_AIO_XFER_MAX
4577 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4578#endif
4579#ifdef _PC_ABI_ASYNC_IO
4580 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4581#endif
Fred Drakec9680921999-12-13 16:37:25 +00004582#ifdef _PC_ASYNC_IO
4583 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4584#endif
4585#ifdef _PC_CHOWN_RESTRICTED
4586 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4587#endif
4588#ifdef _PC_FILESIZEBITS
4589 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4590#endif
4591#ifdef _PC_LAST
4592 {"PC_LAST", _PC_LAST},
4593#endif
4594#ifdef _PC_LINK_MAX
4595 {"PC_LINK_MAX", _PC_LINK_MAX},
4596#endif
4597#ifdef _PC_MAX_CANON
4598 {"PC_MAX_CANON", _PC_MAX_CANON},
4599#endif
4600#ifdef _PC_MAX_INPUT
4601 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4602#endif
4603#ifdef _PC_NAME_MAX
4604 {"PC_NAME_MAX", _PC_NAME_MAX},
4605#endif
4606#ifdef _PC_NO_TRUNC
4607 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4608#endif
4609#ifdef _PC_PATH_MAX
4610 {"PC_PATH_MAX", _PC_PATH_MAX},
4611#endif
4612#ifdef _PC_PIPE_BUF
4613 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4614#endif
4615#ifdef _PC_PRIO_IO
4616 {"PC_PRIO_IO", _PC_PRIO_IO},
4617#endif
4618#ifdef _PC_SOCK_MAXBUF
4619 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4620#endif
4621#ifdef _PC_SYNC_IO
4622 {"PC_SYNC_IO", _PC_SYNC_IO},
4623#endif
4624#ifdef _PC_VDISABLE
4625 {"PC_VDISABLE", _PC_VDISABLE},
4626#endif
4627};
4628
Fred Drakec9680921999-12-13 16:37:25 +00004629static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004630conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004631{
4632 return conv_confname(arg, valuep, posix_constants_pathconf,
4633 sizeof(posix_constants_pathconf)
4634 / sizeof(struct constdef));
4635}
4636#endif
4637
4638#ifdef HAVE_FPATHCONF
4639static char posix_fpathconf__doc__[] = "\
4640fpathconf(fd, name) -> integer\n\
4641Return the configuration limit name for the file descriptor fd.\n\
4642If there is no limit, return -1.";
4643
4644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004645posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004646{
4647 PyObject *result = NULL;
4648 int name, fd;
4649
Fred Drake12c6e2d1999-12-14 21:25:03 +00004650 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4651 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004652 long limit;
4653
4654 errno = 0;
4655 limit = fpathconf(fd, name);
4656 if (limit == -1 && errno != 0)
4657 posix_error();
4658 else
4659 result = PyInt_FromLong(limit);
4660 }
4661 return result;
4662}
4663#endif
4664
4665
4666#ifdef HAVE_PATHCONF
4667static char posix_pathconf__doc__[] = "\
4668pathconf(path, name) -> integer\n\
4669Return the configuration limit name for the file or directory path.\n\
4670If there is no limit, return -1.";
4671
4672static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004673posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004674{
4675 PyObject *result = NULL;
4676 int name;
4677 char *path;
4678
4679 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4680 conv_path_confname, &name)) {
4681 long limit;
4682
4683 errno = 0;
4684 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004685 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004686 if (errno == EINVAL)
4687 /* could be a path or name problem */
4688 posix_error();
4689 else
4690 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004691 }
Fred Drakec9680921999-12-13 16:37:25 +00004692 else
4693 result = PyInt_FromLong(limit);
4694 }
4695 return result;
4696}
4697#endif
4698
4699#ifdef HAVE_CONFSTR
4700static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004701#ifdef _CS_ARCHITECTURE
4702 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4703#endif
4704#ifdef _CS_HOSTNAME
4705 {"CS_HOSTNAME", _CS_HOSTNAME},
4706#endif
4707#ifdef _CS_HW_PROVIDER
4708 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4709#endif
4710#ifdef _CS_HW_SERIAL
4711 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4712#endif
4713#ifdef _CS_INITTAB_NAME
4714 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4715#endif
Fred Drakec9680921999-12-13 16:37:25 +00004716#ifdef _CS_LFS64_CFLAGS
4717 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4718#endif
4719#ifdef _CS_LFS64_LDFLAGS
4720 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4721#endif
4722#ifdef _CS_LFS64_LIBS
4723 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4724#endif
4725#ifdef _CS_LFS64_LINTFLAGS
4726 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4727#endif
4728#ifdef _CS_LFS_CFLAGS
4729 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4730#endif
4731#ifdef _CS_LFS_LDFLAGS
4732 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4733#endif
4734#ifdef _CS_LFS_LIBS
4735 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4736#endif
4737#ifdef _CS_LFS_LINTFLAGS
4738 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4739#endif
Fred Draked86ed291999-12-15 15:34:33 +00004740#ifdef _CS_MACHINE
4741 {"CS_MACHINE", _CS_MACHINE},
4742#endif
Fred Drakec9680921999-12-13 16:37:25 +00004743#ifdef _CS_PATH
4744 {"CS_PATH", _CS_PATH},
4745#endif
Fred Draked86ed291999-12-15 15:34:33 +00004746#ifdef _CS_RELEASE
4747 {"CS_RELEASE", _CS_RELEASE},
4748#endif
4749#ifdef _CS_SRPC_DOMAIN
4750 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4751#endif
4752#ifdef _CS_SYSNAME
4753 {"CS_SYSNAME", _CS_SYSNAME},
4754#endif
4755#ifdef _CS_VERSION
4756 {"CS_VERSION", _CS_VERSION},
4757#endif
Fred Drakec9680921999-12-13 16:37:25 +00004758#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4759 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4760#endif
4761#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4762 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4763#endif
4764#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4765 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4766#endif
4767#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4768 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4769#endif
4770#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4771 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4772#endif
4773#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4774 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4775#endif
4776#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4777 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4778#endif
4779#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4780 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4781#endif
4782#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4783 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4784#endif
4785#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4786 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4787#endif
4788#ifdef _CS_XBS5_LP64_OFF64_LIBS
4789 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4790#endif
4791#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4792 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4793#endif
4794#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4795 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4796#endif
4797#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4798 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4799#endif
4800#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4801 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4802#endif
4803#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4804 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4805#endif
Fred Draked86ed291999-12-15 15:34:33 +00004806#ifdef _MIPS_CS_AVAIL_PROCESSORS
4807 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4808#endif
4809#ifdef _MIPS_CS_BASE
4810 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4811#endif
4812#ifdef _MIPS_CS_HOSTID
4813 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4814#endif
4815#ifdef _MIPS_CS_HW_NAME
4816 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4817#endif
4818#ifdef _MIPS_CS_NUM_PROCESSORS
4819 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4820#endif
4821#ifdef _MIPS_CS_OSREL_MAJ
4822 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4823#endif
4824#ifdef _MIPS_CS_OSREL_MIN
4825 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4826#endif
4827#ifdef _MIPS_CS_OSREL_PATCH
4828 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4829#endif
4830#ifdef _MIPS_CS_OS_NAME
4831 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4832#endif
4833#ifdef _MIPS_CS_OS_PROVIDER
4834 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4835#endif
4836#ifdef _MIPS_CS_PROCESSORS
4837 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4838#endif
4839#ifdef _MIPS_CS_SERIAL
4840 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4841#endif
4842#ifdef _MIPS_CS_VENDOR
4843 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4844#endif
Fred Drakec9680921999-12-13 16:37:25 +00004845};
4846
4847static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004848conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004849{
4850 return conv_confname(arg, valuep, posix_constants_confstr,
4851 sizeof(posix_constants_confstr)
4852 / sizeof(struct constdef));
4853}
4854
4855static char posix_confstr__doc__[] = "\
4856confstr(name) -> string\n\
4857Return a string-valued system configuration variable.";
4858
4859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004860posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004861{
4862 PyObject *result = NULL;
4863 int name;
4864 char buffer[64];
4865
4866 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4867 int len = confstr(name, buffer, sizeof(buffer));
4868
Fred Drakec9680921999-12-13 16:37:25 +00004869 errno = 0;
4870 if (len == 0) {
4871 if (errno != 0)
4872 posix_error();
4873 else
4874 result = PyString_FromString("");
4875 }
4876 else {
4877 if (len >= sizeof(buffer)) {
4878 result = PyString_FromStringAndSize(NULL, len);
4879 if (result != NULL)
4880 confstr(name, PyString_AS_STRING(result), len+1);
4881 }
4882 else
4883 result = PyString_FromString(buffer);
4884 }
4885 }
4886 return result;
4887}
4888#endif
4889
4890
4891#ifdef HAVE_SYSCONF
4892static struct constdef posix_constants_sysconf[] = {
4893#ifdef _SC_2_CHAR_TERM
4894 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4895#endif
4896#ifdef _SC_2_C_BIND
4897 {"SC_2_C_BIND", _SC_2_C_BIND},
4898#endif
4899#ifdef _SC_2_C_DEV
4900 {"SC_2_C_DEV", _SC_2_C_DEV},
4901#endif
4902#ifdef _SC_2_C_VERSION
4903 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4904#endif
4905#ifdef _SC_2_FORT_DEV
4906 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4907#endif
4908#ifdef _SC_2_FORT_RUN
4909 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4910#endif
4911#ifdef _SC_2_LOCALEDEF
4912 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4913#endif
4914#ifdef _SC_2_SW_DEV
4915 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4916#endif
4917#ifdef _SC_2_UPE
4918 {"SC_2_UPE", _SC_2_UPE},
4919#endif
4920#ifdef _SC_2_VERSION
4921 {"SC_2_VERSION", _SC_2_VERSION},
4922#endif
Fred Draked86ed291999-12-15 15:34:33 +00004923#ifdef _SC_ABI_ASYNCHRONOUS_IO
4924 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4925#endif
4926#ifdef _SC_ACL
4927 {"SC_ACL", _SC_ACL},
4928#endif
Fred Drakec9680921999-12-13 16:37:25 +00004929#ifdef _SC_AIO_LISTIO_MAX
4930 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4931#endif
Fred Drakec9680921999-12-13 16:37:25 +00004932#ifdef _SC_AIO_MAX
4933 {"SC_AIO_MAX", _SC_AIO_MAX},
4934#endif
4935#ifdef _SC_AIO_PRIO_DELTA_MAX
4936 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4937#endif
4938#ifdef _SC_ARG_MAX
4939 {"SC_ARG_MAX", _SC_ARG_MAX},
4940#endif
4941#ifdef _SC_ASYNCHRONOUS_IO
4942 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4943#endif
4944#ifdef _SC_ATEXIT_MAX
4945 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4946#endif
Fred Draked86ed291999-12-15 15:34:33 +00004947#ifdef _SC_AUDIT
4948 {"SC_AUDIT", _SC_AUDIT},
4949#endif
Fred Drakec9680921999-12-13 16:37:25 +00004950#ifdef _SC_AVPHYS_PAGES
4951 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4952#endif
4953#ifdef _SC_BC_BASE_MAX
4954 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4955#endif
4956#ifdef _SC_BC_DIM_MAX
4957 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4958#endif
4959#ifdef _SC_BC_SCALE_MAX
4960 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4961#endif
4962#ifdef _SC_BC_STRING_MAX
4963 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4964#endif
Fred Draked86ed291999-12-15 15:34:33 +00004965#ifdef _SC_CAP
4966 {"SC_CAP", _SC_CAP},
4967#endif
Fred Drakec9680921999-12-13 16:37:25 +00004968#ifdef _SC_CHARCLASS_NAME_MAX
4969 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4970#endif
4971#ifdef _SC_CHAR_BIT
4972 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4973#endif
4974#ifdef _SC_CHAR_MAX
4975 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4976#endif
4977#ifdef _SC_CHAR_MIN
4978 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4979#endif
4980#ifdef _SC_CHILD_MAX
4981 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4982#endif
4983#ifdef _SC_CLK_TCK
4984 {"SC_CLK_TCK", _SC_CLK_TCK},
4985#endif
4986#ifdef _SC_COHER_BLKSZ
4987 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4988#endif
4989#ifdef _SC_COLL_WEIGHTS_MAX
4990 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4991#endif
4992#ifdef _SC_DCACHE_ASSOC
4993 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4994#endif
4995#ifdef _SC_DCACHE_BLKSZ
4996 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4997#endif
4998#ifdef _SC_DCACHE_LINESZ
4999 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5000#endif
5001#ifdef _SC_DCACHE_SZ
5002 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5003#endif
5004#ifdef _SC_DCACHE_TBLKSZ
5005 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5006#endif
5007#ifdef _SC_DELAYTIMER_MAX
5008 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5009#endif
5010#ifdef _SC_EQUIV_CLASS_MAX
5011 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5012#endif
5013#ifdef _SC_EXPR_NEST_MAX
5014 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5015#endif
5016#ifdef _SC_FSYNC
5017 {"SC_FSYNC", _SC_FSYNC},
5018#endif
5019#ifdef _SC_GETGR_R_SIZE_MAX
5020 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5021#endif
5022#ifdef _SC_GETPW_R_SIZE_MAX
5023 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5024#endif
5025#ifdef _SC_ICACHE_ASSOC
5026 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5027#endif
5028#ifdef _SC_ICACHE_BLKSZ
5029 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5030#endif
5031#ifdef _SC_ICACHE_LINESZ
5032 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5033#endif
5034#ifdef _SC_ICACHE_SZ
5035 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5036#endif
Fred Draked86ed291999-12-15 15:34:33 +00005037#ifdef _SC_INF
5038 {"SC_INF", _SC_INF},
5039#endif
Fred Drakec9680921999-12-13 16:37:25 +00005040#ifdef _SC_INT_MAX
5041 {"SC_INT_MAX", _SC_INT_MAX},
5042#endif
5043#ifdef _SC_INT_MIN
5044 {"SC_INT_MIN", _SC_INT_MIN},
5045#endif
5046#ifdef _SC_IOV_MAX
5047 {"SC_IOV_MAX", _SC_IOV_MAX},
5048#endif
Fred Draked86ed291999-12-15 15:34:33 +00005049#ifdef _SC_IP_SECOPTS
5050 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5051#endif
Fred Drakec9680921999-12-13 16:37:25 +00005052#ifdef _SC_JOB_CONTROL
5053 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5054#endif
Fred Draked86ed291999-12-15 15:34:33 +00005055#ifdef _SC_KERN_POINTERS
5056 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5057#endif
5058#ifdef _SC_KERN_SIM
5059 {"SC_KERN_SIM", _SC_KERN_SIM},
5060#endif
Fred Drakec9680921999-12-13 16:37:25 +00005061#ifdef _SC_LINE_MAX
5062 {"SC_LINE_MAX", _SC_LINE_MAX},
5063#endif
5064#ifdef _SC_LOGIN_NAME_MAX
5065 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5066#endif
5067#ifdef _SC_LOGNAME_MAX
5068 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5069#endif
5070#ifdef _SC_LONG_BIT
5071 {"SC_LONG_BIT", _SC_LONG_BIT},
5072#endif
Fred Draked86ed291999-12-15 15:34:33 +00005073#ifdef _SC_MAC
5074 {"SC_MAC", _SC_MAC},
5075#endif
Fred Drakec9680921999-12-13 16:37:25 +00005076#ifdef _SC_MAPPED_FILES
5077 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5078#endif
5079#ifdef _SC_MAXPID
5080 {"SC_MAXPID", _SC_MAXPID},
5081#endif
5082#ifdef _SC_MB_LEN_MAX
5083 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5084#endif
5085#ifdef _SC_MEMLOCK
5086 {"SC_MEMLOCK", _SC_MEMLOCK},
5087#endif
5088#ifdef _SC_MEMLOCK_RANGE
5089 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5090#endif
5091#ifdef _SC_MEMORY_PROTECTION
5092 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5093#endif
5094#ifdef _SC_MESSAGE_PASSING
5095 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5096#endif
Fred Draked86ed291999-12-15 15:34:33 +00005097#ifdef _SC_MMAP_FIXED_ALIGNMENT
5098 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5099#endif
Fred Drakec9680921999-12-13 16:37:25 +00005100#ifdef _SC_MQ_OPEN_MAX
5101 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5102#endif
5103#ifdef _SC_MQ_PRIO_MAX
5104 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5105#endif
Fred Draked86ed291999-12-15 15:34:33 +00005106#ifdef _SC_NACLS_MAX
5107 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5108#endif
Fred Drakec9680921999-12-13 16:37:25 +00005109#ifdef _SC_NGROUPS_MAX
5110 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5111#endif
5112#ifdef _SC_NL_ARGMAX
5113 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5114#endif
5115#ifdef _SC_NL_LANGMAX
5116 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5117#endif
5118#ifdef _SC_NL_MSGMAX
5119 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5120#endif
5121#ifdef _SC_NL_NMAX
5122 {"SC_NL_NMAX", _SC_NL_NMAX},
5123#endif
5124#ifdef _SC_NL_SETMAX
5125 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5126#endif
5127#ifdef _SC_NL_TEXTMAX
5128 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5129#endif
5130#ifdef _SC_NPROCESSORS_CONF
5131 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5132#endif
5133#ifdef _SC_NPROCESSORS_ONLN
5134 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5135#endif
Fred Draked86ed291999-12-15 15:34:33 +00005136#ifdef _SC_NPROC_CONF
5137 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5138#endif
5139#ifdef _SC_NPROC_ONLN
5140 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5141#endif
Fred Drakec9680921999-12-13 16:37:25 +00005142#ifdef _SC_NZERO
5143 {"SC_NZERO", _SC_NZERO},
5144#endif
5145#ifdef _SC_OPEN_MAX
5146 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5147#endif
5148#ifdef _SC_PAGESIZE
5149 {"SC_PAGESIZE", _SC_PAGESIZE},
5150#endif
5151#ifdef _SC_PAGE_SIZE
5152 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5153#endif
5154#ifdef _SC_PASS_MAX
5155 {"SC_PASS_MAX", _SC_PASS_MAX},
5156#endif
5157#ifdef _SC_PHYS_PAGES
5158 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5159#endif
5160#ifdef _SC_PII
5161 {"SC_PII", _SC_PII},
5162#endif
5163#ifdef _SC_PII_INTERNET
5164 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5165#endif
5166#ifdef _SC_PII_INTERNET_DGRAM
5167 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5168#endif
5169#ifdef _SC_PII_INTERNET_STREAM
5170 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5171#endif
5172#ifdef _SC_PII_OSI
5173 {"SC_PII_OSI", _SC_PII_OSI},
5174#endif
5175#ifdef _SC_PII_OSI_CLTS
5176 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5177#endif
5178#ifdef _SC_PII_OSI_COTS
5179 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5180#endif
5181#ifdef _SC_PII_OSI_M
5182 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5183#endif
5184#ifdef _SC_PII_SOCKET
5185 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5186#endif
5187#ifdef _SC_PII_XTI
5188 {"SC_PII_XTI", _SC_PII_XTI},
5189#endif
5190#ifdef _SC_POLL
5191 {"SC_POLL", _SC_POLL},
5192#endif
5193#ifdef _SC_PRIORITIZED_IO
5194 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5195#endif
5196#ifdef _SC_PRIORITY_SCHEDULING
5197 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5198#endif
5199#ifdef _SC_REALTIME_SIGNALS
5200 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5201#endif
5202#ifdef _SC_RE_DUP_MAX
5203 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5204#endif
5205#ifdef _SC_RTSIG_MAX
5206 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5207#endif
5208#ifdef _SC_SAVED_IDS
5209 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5210#endif
5211#ifdef _SC_SCHAR_MAX
5212 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5213#endif
5214#ifdef _SC_SCHAR_MIN
5215 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5216#endif
5217#ifdef _SC_SELECT
5218 {"SC_SELECT", _SC_SELECT},
5219#endif
5220#ifdef _SC_SEMAPHORES
5221 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5222#endif
5223#ifdef _SC_SEM_NSEMS_MAX
5224 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5225#endif
5226#ifdef _SC_SEM_VALUE_MAX
5227 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5228#endif
5229#ifdef _SC_SHARED_MEMORY_OBJECTS
5230 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5231#endif
5232#ifdef _SC_SHRT_MAX
5233 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5234#endif
5235#ifdef _SC_SHRT_MIN
5236 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5237#endif
5238#ifdef _SC_SIGQUEUE_MAX
5239 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5240#endif
5241#ifdef _SC_SIGRT_MAX
5242 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5243#endif
5244#ifdef _SC_SIGRT_MIN
5245 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5246#endif
Fred Draked86ed291999-12-15 15:34:33 +00005247#ifdef _SC_SOFTPOWER
5248 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5249#endif
Fred Drakec9680921999-12-13 16:37:25 +00005250#ifdef _SC_SPLIT_CACHE
5251 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5252#endif
5253#ifdef _SC_SSIZE_MAX
5254 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5255#endif
5256#ifdef _SC_STACK_PROT
5257 {"SC_STACK_PROT", _SC_STACK_PROT},
5258#endif
5259#ifdef _SC_STREAM_MAX
5260 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5261#endif
5262#ifdef _SC_SYNCHRONIZED_IO
5263 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5264#endif
5265#ifdef _SC_THREADS
5266 {"SC_THREADS", _SC_THREADS},
5267#endif
5268#ifdef _SC_THREAD_ATTR_STACKADDR
5269 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5270#endif
5271#ifdef _SC_THREAD_ATTR_STACKSIZE
5272 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5273#endif
5274#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5275 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5276#endif
5277#ifdef _SC_THREAD_KEYS_MAX
5278 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5279#endif
5280#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5281 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5282#endif
5283#ifdef _SC_THREAD_PRIO_INHERIT
5284 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5285#endif
5286#ifdef _SC_THREAD_PRIO_PROTECT
5287 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5288#endif
5289#ifdef _SC_THREAD_PROCESS_SHARED
5290 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5291#endif
5292#ifdef _SC_THREAD_SAFE_FUNCTIONS
5293 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5294#endif
5295#ifdef _SC_THREAD_STACK_MIN
5296 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5297#endif
5298#ifdef _SC_THREAD_THREADS_MAX
5299 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5300#endif
5301#ifdef _SC_TIMERS
5302 {"SC_TIMERS", _SC_TIMERS},
5303#endif
5304#ifdef _SC_TIMER_MAX
5305 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5306#endif
5307#ifdef _SC_TTY_NAME_MAX
5308 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5309#endif
5310#ifdef _SC_TZNAME_MAX
5311 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5312#endif
5313#ifdef _SC_T_IOV_MAX
5314 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5315#endif
5316#ifdef _SC_UCHAR_MAX
5317 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5318#endif
5319#ifdef _SC_UINT_MAX
5320 {"SC_UINT_MAX", _SC_UINT_MAX},
5321#endif
5322#ifdef _SC_UIO_MAXIOV
5323 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5324#endif
5325#ifdef _SC_ULONG_MAX
5326 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5327#endif
5328#ifdef _SC_USHRT_MAX
5329 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5330#endif
5331#ifdef _SC_VERSION
5332 {"SC_VERSION", _SC_VERSION},
5333#endif
5334#ifdef _SC_WORD_BIT
5335 {"SC_WORD_BIT", _SC_WORD_BIT},
5336#endif
5337#ifdef _SC_XBS5_ILP32_OFF32
5338 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5339#endif
5340#ifdef _SC_XBS5_ILP32_OFFBIG
5341 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5342#endif
5343#ifdef _SC_XBS5_LP64_OFF64
5344 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5345#endif
5346#ifdef _SC_XBS5_LPBIG_OFFBIG
5347 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5348#endif
5349#ifdef _SC_XOPEN_CRYPT
5350 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5351#endif
5352#ifdef _SC_XOPEN_ENH_I18N
5353 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5354#endif
5355#ifdef _SC_XOPEN_LEGACY
5356 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5357#endif
5358#ifdef _SC_XOPEN_REALTIME
5359 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5360#endif
5361#ifdef _SC_XOPEN_REALTIME_THREADS
5362 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5363#endif
5364#ifdef _SC_XOPEN_SHM
5365 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5366#endif
5367#ifdef _SC_XOPEN_UNIX
5368 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5369#endif
5370#ifdef _SC_XOPEN_VERSION
5371 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5372#endif
5373#ifdef _SC_XOPEN_XCU_VERSION
5374 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5375#endif
5376#ifdef _SC_XOPEN_XPG2
5377 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5378#endif
5379#ifdef _SC_XOPEN_XPG3
5380 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5381#endif
5382#ifdef _SC_XOPEN_XPG4
5383 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5384#endif
5385};
5386
5387static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005388conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005389{
5390 return conv_confname(arg, valuep, posix_constants_sysconf,
5391 sizeof(posix_constants_sysconf)
5392 / sizeof(struct constdef));
5393}
5394
5395static char posix_sysconf__doc__[] = "\
5396sysconf(name) -> integer\n\
5397Return an integer-valued system configuration variable.";
5398
5399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005400posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005401{
5402 PyObject *result = NULL;
5403 int name;
5404
5405 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5406 int value;
5407
5408 errno = 0;
5409 value = sysconf(name);
5410 if (value == -1 && errno != 0)
5411 posix_error();
5412 else
5413 result = PyInt_FromLong(value);
5414 }
5415 return result;
5416}
5417#endif
5418
5419
Fred Drakebec628d1999-12-15 18:31:10 +00005420/* This code is used to ensure that the tables of configuration value names
5421 * are in sorted order as required by conv_confname(), and also to build the
5422 * the exported dictionaries that are used to publish information about the
5423 * names available on the host platform.
5424 *
5425 * Sorting the table at runtime ensures that the table is properly ordered
5426 * when used, even for platforms we're not able to test on. It also makes
5427 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005428 */
Fred Drakebec628d1999-12-15 18:31:10 +00005429
5430static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005431cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005432{
5433 const struct constdef *c1 =
5434 (const struct constdef *) v1;
5435 const struct constdef *c2 =
5436 (const struct constdef *) v2;
5437
5438 return strcmp(c1->name, c2->name);
5439}
5440
5441static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005442setup_confname_table(struct constdef *table, size_t tablesize,
5443 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005444{
Fred Drakebec628d1999-12-15 18:31:10 +00005445 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005446 size_t i;
5447 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005448
5449 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5450 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005451 if (d == NULL)
5452 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005453
Barry Warsaw3155db32000-04-13 15:20:40 +00005454 for (i=0; i < tablesize; ++i) {
5455 PyObject *o = PyInt_FromLong(table[i].value);
5456 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5457 Py_XDECREF(o);
5458 Py_DECREF(d);
5459 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005460 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005461 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005462 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005463 status = PyDict_SetItemString(moddict, tablename, d);
5464 Py_DECREF(d);
5465 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005466}
5467
Fred Drakebec628d1999-12-15 18:31:10 +00005468/* Return -1 on failure, 0 on success. */
5469static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005470setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005471{
5472#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005473 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005474 sizeof(posix_constants_pathconf)
5475 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005476 "pathconf_names", moddict))
5477 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005478#endif
5479#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005480 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005481 sizeof(posix_constants_confstr)
5482 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005483 "confstr_names", moddict))
5484 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005485#endif
5486#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005487 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005488 sizeof(posix_constants_sysconf)
5489 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005490 "sysconf_names", moddict))
5491 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005492#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005493 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005494}
Fred Draked86ed291999-12-15 15:34:33 +00005495
5496
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005497static char posix_abort__doc__[] = "\
5498abort() -> does not return!\n\
5499Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5500in the hardest way possible on the hosting operating system.";
5501
5502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005503posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005504{
5505 if (!PyArg_ParseTuple(args, ":abort"))
5506 return NULL;
5507 abort();
5508 /*NOTREACHED*/
5509 Py_FatalError("abort() called from Python code didn't abort!");
5510 return NULL;
5511}
Fred Drakebec628d1999-12-15 18:31:10 +00005512
Tim Petersf58a7aa2000-09-22 10:05:54 +00005513#ifdef MS_WIN32
5514static char win32_startfile__doc__[] = "\
5515startfile(filepath) - Start a file with its associated application.\n\
5516\n\
5517This acts like double-clicking the file in Explorer, or giving the file\n\
5518name as an argument to the DOS \"start\" command: the file is opened\n\
5519with whatever application (if any) its extension is associated.\n\
5520\n\
5521startfile returns as soon as the associated application is launched.\n\
5522There is no option to wait for the application to close, and no way\n\
5523to retrieve the application's exit status.\n\
5524\n\
5525The filepath is relative to the current directory. If you want to use\n\
5526an absolute path, make sure the first character is not a slash (\"/\");\n\
5527the underlying Win32 ShellExecute function doesn't work if it is.";
5528
5529static PyObject *
5530win32_startfile(PyObject *self, PyObject *args)
5531{
5532 char *filepath;
5533 HINSTANCE rc;
5534 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5535 return NULL;
5536 Py_BEGIN_ALLOW_THREADS
5537 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5538 Py_END_ALLOW_THREADS
5539 if (rc <= (HINSTANCE)32)
5540 return win32_error("startfile", filepath);
5541 Py_INCREF(Py_None);
5542 return Py_None;
5543}
5544#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005545
5546static PyMethodDef posix_methods[] = {
5547 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5548#ifdef HAVE_TTYNAME
5549 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5550#endif
5551 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5552 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005553#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005554 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005555#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005556#ifdef HAVE_CHROOT
5557 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5558#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005559#ifdef HAVE_CTERMID
5560 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5561#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005562#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005563 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005564#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005565#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005566 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005567#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005568 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5569 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5570 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005571#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005572 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005573#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005574#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005575 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005576#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005577 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5578 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5579 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005580#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005581 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005582#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005583#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005584 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005585#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005586 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005587#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005588 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005589#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005590 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5591 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5592 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005593#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005594 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005595#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005596 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005597#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005598 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5599 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005600#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005601#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005602 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5603 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005604#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005605#ifdef HAVE_FORK1
5606 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5607#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005608#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005609 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005610#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005611#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005612 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005613#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005614#ifdef HAVE_FORKPTY
5615 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5616#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005617#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005618 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005619#endif /* HAVE_GETEGID */
5620#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005621 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005622#endif /* HAVE_GETEUID */
5623#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005624 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005625#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005626#ifdef HAVE_GETGROUPS
5627 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5628#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005629 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005630#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005631 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005632#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005633#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005634 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005635#endif /* HAVE_GETPPID */
5636#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005637 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005638#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005639#ifdef HAVE_GETLOGIN
5640 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5641#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005642#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005643 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005644#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005645#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005646 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005647#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005648#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005649 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005650#ifdef MS_WIN32
5651 {"popen2", win32_popen2, METH_VARARGS},
5652 {"popen3", win32_popen3, METH_VARARGS},
5653 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005654 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005655#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005656#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005657#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005658 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005659#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005660#ifdef HAVE_SETEUID
5661 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5662#endif /* HAVE_SETEUID */
5663#ifdef HAVE_SETEGID
5664 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5665#endif /* HAVE_SETEGID */
5666#ifdef HAVE_SETREUID
5667 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5668#endif /* HAVE_SETREUID */
5669#ifdef HAVE_SETREGID
5670 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5671#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005672#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005673 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005674#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005675#ifdef HAVE_SETGROUPS
5676 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5677#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005678#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005679 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005680#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005681#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005682 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005683#endif /* HAVE_WAIT */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005684#ifdef HAVE_WAITPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005685 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005686#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005687#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005688 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005689#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005690#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005691 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005692#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005693#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005694 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005695#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005696#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005697 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005698#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005699 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5700 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5701 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5702 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5703 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5704 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5705 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5706 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5707 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005708 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005709#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005710 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005711#endif
5712#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005713 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005714#endif
5715#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005716 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005717#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005718#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005719 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005720#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005721#ifdef HAVE_UNSETENV
5722 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
5723#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005724#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005725 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005726#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005727#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005728 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005729#endif
5730#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005731 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005732#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005733#ifdef HAVE_SYS_WAIT_H
5734#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005735 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005736#endif /* WIFSTOPPED */
5737#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005738 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005739#endif /* WIFSIGNALED */
5740#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005741 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005742#endif /* WIFEXITED */
5743#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005744 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005745#endif /* WEXITSTATUS */
5746#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005747 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005748#endif /* WTERMSIG */
5749#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005750 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005751#endif /* WSTOPSIG */
5752#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005753#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005754 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005755#endif
5756#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005757 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005758#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005759#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005760 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5761#endif
5762#ifdef HAVE_TEMPNAM
5763 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5764#endif
5765#ifdef HAVE_TMPNAM
5766 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5767#endif
Fred Drakec9680921999-12-13 16:37:25 +00005768#ifdef HAVE_CONFSTR
5769 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5770#endif
5771#ifdef HAVE_SYSCONF
5772 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5773#endif
5774#ifdef HAVE_FPATHCONF
5775 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5776#endif
5777#ifdef HAVE_PATHCONF
5778 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5779#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005780 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005781#ifdef MS_WIN32
5782 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5783#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005784 {NULL, NULL} /* Sentinel */
5785};
5786
5787
Barry Warsaw4a342091996-12-19 23:50:02 +00005788static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005789ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005790{
5791 PyObject* v = PyInt_FromLong(value);
5792 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5793 return -1; /* triggers fatal error */
5794
5795 Py_DECREF(v);
5796 return 0;
5797}
5798
Guido van Rossumd48f2521997-12-05 22:19:34 +00005799#if defined(PYOS_OS2)
5800/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5801static int insertvalues(PyObject *d)
5802{
5803 APIRET rc;
5804 ULONG values[QSV_MAX+1];
5805 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00005806 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00005807
5808 Py_BEGIN_ALLOW_THREADS
5809 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5810 Py_END_ALLOW_THREADS
5811
5812 if (rc != NO_ERROR) {
5813 os2_error(rc);
5814 return -1;
5815 }
5816
5817 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5818 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5819 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5820 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5821 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5822 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5823 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5824
5825 switch (values[QSV_VERSION_MINOR]) {
5826 case 0: ver = "2.00"; break;
5827 case 10: ver = "2.10"; break;
5828 case 11: ver = "2.11"; break;
5829 case 30: ver = "3.00"; break;
5830 case 40: ver = "4.00"; break;
5831 case 50: ver = "5.00"; break;
5832 default:
Tim Peters885d4572001-11-28 20:27:42 +00005833 PyOS_snprintf(tmp, sizeof(tmp),
5834 "%d-%d", values[QSV_VERSION_MAJOR],
5835 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005836 ver = &tmp[0];
5837 }
5838
5839 /* Add Indicator of the Version of the Operating System */
5840 v = PyString_FromString(ver);
5841 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5842 return -1;
5843 Py_DECREF(v);
5844
5845 /* Add Indicator of Which Drive was Used to Boot the System */
5846 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5847 tmp[1] = ':';
5848 tmp[2] = '\0';
5849
5850 v = PyString_FromString(tmp);
5851 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5852 return -1;
5853 Py_DECREF(v);
5854
5855 return 0;
5856}
5857#endif
5858
Barry Warsaw4a342091996-12-19 23:50:02 +00005859static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005860all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005861{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005862#ifdef F_OK
5863 if (ins(d, "F_OK", (long)F_OK)) return -1;
5864#endif
5865#ifdef R_OK
5866 if (ins(d, "R_OK", (long)R_OK)) return -1;
5867#endif
5868#ifdef W_OK
5869 if (ins(d, "W_OK", (long)W_OK)) return -1;
5870#endif
5871#ifdef X_OK
5872 if (ins(d, "X_OK", (long)X_OK)) return -1;
5873#endif
Fred Drakec9680921999-12-13 16:37:25 +00005874#ifdef NGROUPS_MAX
5875 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5876#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005877#ifdef TMP_MAX
5878 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5879#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005880#ifdef WNOHANG
5881 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5882#endif
5883#ifdef O_RDONLY
5884 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5885#endif
5886#ifdef O_WRONLY
5887 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5888#endif
5889#ifdef O_RDWR
5890 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5891#endif
5892#ifdef O_NDELAY
5893 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5894#endif
5895#ifdef O_NONBLOCK
5896 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5897#endif
5898#ifdef O_APPEND
5899 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5900#endif
5901#ifdef O_DSYNC
5902 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5903#endif
5904#ifdef O_RSYNC
5905 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5906#endif
5907#ifdef O_SYNC
5908 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5909#endif
5910#ifdef O_NOCTTY
5911 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5912#endif
5913#ifdef O_CREAT
5914 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5915#endif
5916#ifdef O_EXCL
5917 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5918#endif
5919#ifdef O_TRUNC
5920 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5921#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005922#ifdef O_BINARY
5923 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5924#endif
5925#ifdef O_TEXT
5926 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5927#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005928#ifdef O_LARGEFILE
5929 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
5930#endif
5931
5932/* GNU extensions. */
5933#ifdef O_DIRECT
5934 /* Direct disk access. */
5935 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
5936#endif
5937#ifdef O_DIRECTORY
5938 /* Must be a directory. */
5939 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
5940#endif
5941#ifdef O_NOFOLLOW
5942 /* Do not follow links. */
5943 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
5944#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005945
Guido van Rossum246bc171999-02-01 23:54:31 +00005946#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005947 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5948 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5949 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5950 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5951 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005952#endif
5953
Guido van Rossumd48f2521997-12-05 22:19:34 +00005954#if defined(PYOS_OS2)
5955 if (insertvalues(d)) return -1;
5956#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005957 return 0;
5958}
5959
5960
Tim Peters58e0a8c2001-05-14 22:32:33 +00005961#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005962#define INITFUNC initnt
5963#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005964
5965#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005966#define INITFUNC initos2
5967#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005968
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005969#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005970#define INITFUNC initposix
5971#define MODNAME "posix"
5972#endif
5973
Guido van Rossum3886bb61998-12-04 18:50:17 +00005974DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005975INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005976{
Barry Warsaw53699e91996-12-10 23:23:01 +00005977 PyObject *m, *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00005978
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005979 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005980 posix_methods,
5981 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005982 (PyObject *)NULL,
5983 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005984 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005985
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005986 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005987 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005988 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005989 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005990 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005991
Barry Warsaw4a342091996-12-19 23:50:02 +00005992 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005993 return;
5994
Fred Drakebec628d1999-12-15 18:31:10 +00005995 if (setup_confname_tables(d))
5996 return;
5997
Barry Warsawca74da41999-02-09 19:31:45 +00005998 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005999
Guido van Rossumb3d39562000-01-31 18:41:26 +00006000#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006001 if (posix_putenv_garbage == NULL)
6002 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006003#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006004
Guido van Rossum14648392001-12-08 18:02:58 +00006005 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006006 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
6007 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
6008
Guido van Rossum14648392001-12-08 18:02:58 +00006009 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006010 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
6011 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006012}