blob: 25da18ff984c90d1c1221f14855dd063af93e80d [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +000049/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000050/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000051#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000052#include <process.h>
53#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000054#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000055#define HAVE_GETCWD 1
56#define HAVE_OPENDIR 1
57#define HAVE_SYSTEM 1
58#if defined(__OS2__)
59#define HAVE_EXECV 1
60#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000061#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000062#include <process.h>
63#else
64#ifdef __BORLANDC__ /* Borland compiler */
65#define HAVE_EXECV 1
66#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000067#define HAVE_OPENDIR 1
68#define HAVE_PIPE 1
69#define HAVE_POPEN 1
70#define HAVE_SYSTEM 1
71#define HAVE_WAIT 1
72#else
73#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000074#define HAVE_GETCWD 1
75#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000076#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#define HAVE_EXECV 1
78#define HAVE_PIPE 1
79#define HAVE_POPEN 1
80#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000081#define HAVE_CWAIT 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000083#endif /* !MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000084#else /* all other compilers */
85/* Unix functions that the configure script doesn't check for */
86#define HAVE_EXECV 1
87#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000088#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
89#define HAVE_FORK1 1
90#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000091#define HAVE_GETCWD 1
92#define HAVE_GETEGID 1
93#define HAVE_GETEUID 1
94#define HAVE_GETGID 1
95#define HAVE_GETPPID 1
96#define HAVE_GETUID 1
97#define HAVE_KILL 1
98#define HAVE_OPENDIR 1
99#define HAVE_PIPE 1
100#define HAVE_POPEN 1
101#define HAVE_SYSTEM 1
102#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000103#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000104#endif /* _MSC_VER */
105#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000106#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000107#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000108
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000109#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000110
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000111#if defined(sun) && !defined(__SVR4)
112/* SunOS 4.1.4 doesn't have prototypes for these: */
113extern int rename(const char *, const char *);
114extern int pclose(FILE *);
115extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000116extern int fsync(int);
117extern int lstat(const char *, struct stat *);
118extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000119#endif
120
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000121#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000122#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000123extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000124#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000125#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000126extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000127#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000128extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000129#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000130#endif
131#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000132extern int chdir(char *);
133extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000134#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000135extern int chdir(const char *);
136extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000137#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000138#ifdef __BORLANDC__
139extern int chmod(const char *, int);
140#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000141extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000142#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int chown(const char *, uid_t, gid_t);
144extern char *getcwd(char *, int);
145extern char *strerror(int);
146extern int link(const char *, const char *);
147extern int rename(const char *, const char *);
148extern int stat(const char *, struct stat *);
149extern int unlink(const char *);
150extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000151#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000153#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000154#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000156#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000157#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000158
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160
Guido van Rossumb6775db1994-08-01 11:34:53 +0000161#ifdef HAVE_UTIME_H
162#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000163#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000164
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000165#ifdef HAVE_SYS_UTIME_H
166#include <sys/utime.h>
167#define HAVE_UTIME_H /* pretend we do for the rest of this file */
168#endif /* HAVE_SYS_UTIME_H */
169
Guido van Rossumb6775db1994-08-01 11:34:53 +0000170#ifdef HAVE_SYS_TIMES_H
171#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000172#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000173
174#ifdef HAVE_SYS_PARAM_H
175#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000176#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177
178#ifdef HAVE_SYS_UTSNAME_H
179#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181
182#ifndef MAXPATHLEN
183#define MAXPATHLEN 1024
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000184#endif /* MAXPATHLEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000185
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000186#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000188#define NAMLEN(dirent) strlen((dirent)->d_name)
189#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000190#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000191#include <direct.h>
192#define NAMLEN(dirent) strlen((dirent)->d_name)
193#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000195#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000196#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000197#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#endif
200#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000202#endif
203#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#endif
206#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000208#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#include <direct.h>
210#include <io.h>
211#include <process.h>
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000212#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000214#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000216#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000217#else /* 16-bit Windows */
218#include <dos.h>
219#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000220#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
Guido van Rossumd48f2521997-12-05 22:19:34 +0000223#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000225#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000227#ifdef UNION_WAIT
228/* Emulate some macros on systems that have a union instead of macros */
229
230#ifndef WIFEXITED
231#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
232#endif
233
234#ifndef WEXITSTATUS
235#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
236#endif
237
238#ifndef WTERMSIG
239#define WTERMSIG(u_wait) ((u_wait).w_termsig)
240#endif
241
242#endif /* UNION_WAIT */
243
Greg Wardb48bc172000-03-01 21:51:56 +0000244/* Don't use the "_r" form if we don't need it (also, won't have a
245 prototype for it, at least on Solaris -- maybe others as well?). */
246#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
247#define USE_CTERMID_R
248#endif
249
250#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
251#define USE_TMPNAM_R
252#endif
253
Fred Drake699f3522000-06-29 21:12:41 +0000254/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000255#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000256#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000257# define STAT _stati64
258# define FSTAT _fstati64
259# define STRUCT_STAT struct _stati64
260#else
261# define STAT stat
262# define FSTAT fstat
263# define STRUCT_STAT struct stat
264#endif
265
266
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267/* Return a dictionary corresponding to the POSIX environment table */
268
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000269#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000271#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272
Barry Warsaw53699e91996-12-10 23:23:01 +0000273static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000274convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000275{
Barry Warsaw53699e91996-12-10 23:23:01 +0000276 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000278 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279 if (d == NULL)
280 return NULL;
281 if (environ == NULL)
282 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000283 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000285 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000286 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287 char *p = strchr(*e, '=');
288 if (p == NULL)
289 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000290 k = PyString_FromStringAndSize(*e, (int)(p-*e));
291 if (k == NULL) {
292 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000294 }
295 v = PyString_FromString(p+1);
296 if (v == NULL) {
297 PyErr_Clear();
298 Py_DECREF(k);
299 continue;
300 }
301 if (PyDict_GetItem(d, k) == NULL) {
302 if (PyDict_SetItem(d, k, v) != 0)
303 PyErr_Clear();
304 }
305 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000306 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000308#if defined(PYOS_OS2)
309 {
310 APIRET rc;
311 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
312
313 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000314 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000315 PyObject *v = PyString_FromString(buffer);
316 PyDict_SetItemString(d, "BEGINLIBPATH", v);
317 Py_DECREF(v);
318 }
319 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
320 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
321 PyObject *v = PyString_FromString(buffer);
322 PyDict_SetItemString(d, "ENDLIBPATH", v);
323 Py_DECREF(v);
324 }
325 }
326#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000327 return d;
328}
329
330
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331/* Set a POSIX-specific error from errno, and return NULL */
332
Barry Warsawd58d7641998-07-23 16:14:40 +0000333static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000334posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000335{
Barry Warsawca74da41999-02-09 19:31:45 +0000336 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337}
Barry Warsawd58d7641998-07-23 16:14:40 +0000338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000339posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000340{
Barry Warsawca74da41999-02-09 19:31:45 +0000341 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000342}
343
Mark Hammondef8b6542001-05-13 08:04:26 +0000344static PyObject *
345posix_error_with_allocated_filename(char* name)
346{
347 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
348 PyMem_Free(name);
349 return rc;
350}
351
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000352#ifdef MS_WIN32
353static PyObject *
354win32_error(char* function, char* filename)
355{
Mark Hammond33a6da92000-08-15 00:46:38 +0000356 /* XXX We should pass the function name along in the future.
357 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000358 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000359 Windows error object, which is non-trivial.
360 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000361 errno = GetLastError();
362 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000363 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000364 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000365 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000366}
367#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000368
Guido van Rossumd48f2521997-12-05 22:19:34 +0000369#if defined(PYOS_OS2)
370/**********************************************************************
371 * Helper Function to Trim and Format OS/2 Messages
372 **********************************************************************/
373 static void
374os2_formatmsg(char *msgbuf, int msglen, char *reason)
375{
376 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
377
378 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
379 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
380
381 while (lastc > msgbuf && isspace(*lastc))
382 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
383 }
384
385 /* Add Optional Reason Text */
386 if (reason) {
387 strcat(msgbuf, " : ");
388 strcat(msgbuf, reason);
389 }
390}
391
392/**********************************************************************
393 * Decode an OS/2 Operating System Error Code
394 *
395 * A convenience function to lookup an OS/2 error code and return a
396 * text message we can use to raise a Python exception.
397 *
398 * Notes:
399 * The messages for errors returned from the OS/2 kernel reside in
400 * the file OSO001.MSG in the \OS2 directory hierarchy.
401 *
402 **********************************************************************/
403 static char *
404os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
405{
406 APIRET rc;
407 ULONG msglen;
408
409 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
410 Py_BEGIN_ALLOW_THREADS
411 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
412 errorcode, "oso001.msg", &msglen);
413 Py_END_ALLOW_THREADS
414
415 if (rc == NO_ERROR)
416 os2_formatmsg(msgbuf, msglen, reason);
417 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000418 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000419 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000420
421 return msgbuf;
422}
423
424/* Set an OS/2-specific error and return NULL. OS/2 kernel
425 errors are not in a global variable e.g. 'errno' nor are
426 they congruent with posix error numbers. */
427
428static PyObject * os2_error(int code)
429{
430 char text[1024];
431 PyObject *v;
432
433 os2_strerror(text, sizeof(text), code, "");
434
435 v = Py_BuildValue("(is)", code, text);
436 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000437 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000438 Py_DECREF(v);
439 }
440 return NULL; /* Signal to Python that an Exception is Pending */
441}
442
443#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444
445/* POSIX generic methods */
446
Barry Warsaw53699e91996-12-10 23:23:01 +0000447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000448posix_int(PyObject *args, char *format, int (*func)(int))
Guido van Rossum21142a01999-01-08 21:05:37 +0000449{
450 int fd;
451 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000452 if (!PyArg_ParseTuple(args, format, &fd))
Guido van Rossum21142a01999-01-08 21:05:37 +0000453 return NULL;
454 Py_BEGIN_ALLOW_THREADS
455 res = (*func)(fd);
456 Py_END_ALLOW_THREADS
457 if (res < 0)
458 return posix_error();
459 Py_INCREF(Py_None);
460 return Py_None;
461}
462
463
464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000465posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000466{
Mark Hammondef8b6542001-05-13 08:04:26 +0000467 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000468 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000469 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000470 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000471 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000472 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000473 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000474 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000475 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000476 return posix_error_with_allocated_filename(path1);
477 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000478 Py_INCREF(Py_None);
479 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000480}
481
Barry Warsaw53699e91996-12-10 23:23:01 +0000482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000483posix_2str(PyObject *args, char *format,
484 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000485{
Mark Hammondef8b6542001-05-13 08:04:26 +0000486 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000487 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000488 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000489 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000490 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000491 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000492 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000493 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000494 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000495 PyMem_Free(path1);
496 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000497 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000498 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000499 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000500 Py_INCREF(Py_None);
501 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502}
503
Tim Peters5aa91602002-01-30 05:46:57 +0000504static char stat_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000505"stat_result: Result from stat or lstat.\n\n\
506This object may be accessed either as a tuple of\n\
507 (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
508or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
509\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000510Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000511they are available as attributes only.\n\
512\n\
513See os.stat for more information.\n";
514
515static PyStructSequence_Field stat_result_fields[] = {
516 {"st_mode", "protection bits"},
517 {"st_ino", "inode"},
518 {"st_dev", "device"},
519 {"st_nlink", "number of hard links"},
520 {"st_uid", "user ID of owner"},
521 {"st_gid", "group ID of owner"},
522 {"st_size", "total size, in bytes"},
523 {"st_atime", "time of last access"},
524 {"st_mtime", "time of last modification"},
525 {"st_ctime", "time of last change"},
526#ifdef HAVE_ST_BLKSIZE
527 {"st_blksize", "blocksize for filesystem I/O"},
528#endif
529#ifdef HAVE_ST_BLOCKS
530 {"st_blocks", "number of blocks allocated"},
531#endif
532#ifdef HAVE_ST_RDEV
533 {"st_rdev", "device type (if inode device)"},
534#endif
535 {0}
536};
537
538#ifdef HAVE_ST_BLKSIZE
539#define ST_BLKSIZE_IDX 10
540#else
541#define ST_BLKSIZE_IDX 9
542#endif
543
544#ifdef HAVE_ST_BLOCKS
545#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
546#else
547#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
548#endif
549
550#ifdef HAVE_ST_RDEV
551#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
552#else
553#define ST_RDEV_IDX ST_BLOCKS_IDX
554#endif
555
556static PyStructSequence_Desc stat_result_desc = {
557 "stat_result", /* name */
558 stat_result__doc__, /* doc */
559 stat_result_fields,
560 10
561};
562
Tim Peters5aa91602002-01-30 05:46:57 +0000563static char statvfs_result__doc__[] =
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000564"statvfs_result: Result from statvfs or fstatvfs.\n\n\
565This object may be accessed either as a tuple of\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000566 (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),\n\
567or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000568\n\
569See os.statvfs for more information.\n";
570
571static PyStructSequence_Field statvfs_result_fields[] = {
572 {"f_bsize", },
573 {"f_frsize", },
574 {"f_blocks", },
575 {"f_bfree", },
576 {"f_bavail", },
577 {"f_files", },
578 {"f_ffree", },
579 {"f_favail", },
580 {"f_flag", },
581 {"f_namemax",},
582 {0}
583};
584
585static PyStructSequence_Desc statvfs_result_desc = {
586 "statvfs_result", /* name */
587 statvfs_result__doc__, /* doc */
588 statvfs_result_fields,
589 10
590};
591
592static PyTypeObject StatResultType;
593static PyTypeObject StatVFSResultType;
594
Tim Peters5aa91602002-01-30 05:46:57 +0000595/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000596 (used by posix_stat() and posix_fstat()) */
597static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000598_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000599{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000600 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000601 if (v == NULL)
602 return NULL;
603
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000604 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000605#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000606 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000607 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000608#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000609 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000610#endif
611#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000612 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000613 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000614#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000615 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000616#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000617 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
618 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
619 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000620#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000621 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000622 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000623#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000624 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000625#endif
626#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000627 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000628 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000629 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000630 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000631 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000632 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000633#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000634 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
635 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
636 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
637#endif
638
639#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000640 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000641 PyInt_FromLong((long)st.st_blksize));
642#endif
643#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000644 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000645 PyInt_FromLong((long)st.st_blocks));
646#endif
647#ifdef HAVE_ST_RDEV
648 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
649 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000650#endif
651
652 if (PyErr_Occurred()) {
653 Py_DECREF(v);
654 return NULL;
655 }
656
657 return v;
658}
659
Barry Warsaw53699e91996-12-10 23:23:01 +0000660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000661posix_do_stat(PyObject *self, PyObject *args, char *format,
662 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000663{
Fred Drake699f3522000-06-29 21:12:41 +0000664 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000665 char *path = NULL; /* pass this to stat; do not free() it */
666 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000667 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000668
669#ifdef MS_WIN32
Tim Peters500bd032001-12-19 19:05:01 +0000670 int pathlen;
671 char pathcopy[MAX_PATH];
Guido van Rossumace88ae2000-04-21 18:54:45 +0000672#endif /* MS_WIN32 */
673
Tim Peters5aa91602002-01-30 05:46:57 +0000674 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000675 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000676 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000677 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000678
679#ifdef MS_WIN32
680 pathlen = strlen(path);
681 /* the library call can blow up if the file name is too long! */
682 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000683 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000684 errno = ENAMETOOLONG;
685 return posix_error();
686 }
687
Tim Peters500bd032001-12-19 19:05:01 +0000688 /* Remove trailing slash or backslash, unless it's the current
689 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
690 */
691 if (pathlen > 0 &&
692 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
693 /* It does end with a slash -- exempt the root drive cases. */
694 /* XXX UNC root drives should also be exempted? */
695 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
696 /* leave it alone */;
697 else {
698 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000699 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000700 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000701 path = pathcopy;
702 }
703 }
704#endif /* MS_WIN32 */
705
Barry Warsaw53699e91996-12-10 23:23:01 +0000706 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000707 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000708 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000709 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000710 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000711
Tim Peters500bd032001-12-19 19:05:01 +0000712 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000713 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000714}
715
716
717/* POSIX methods */
718
Guido van Rossum94f6f721999-01-06 18:42:14 +0000719static char posix_access__doc__[] =
Guido van Rossum015f22a1999-01-06 22:52:38 +0000720"access(path, mode) -> 1 if granted, 0 otherwise\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000721Test for access to a file.";
722
723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000724posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000725{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000726 char *path;
727 int mode;
728 int res;
729
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000730 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000731 return NULL;
732 Py_BEGIN_ALLOW_THREADS
733 res = access(path, mode);
734 Py_END_ALLOW_THREADS
735 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000736}
737
Guido van Rossumd371ff11999-01-25 16:12:23 +0000738#ifndef F_OK
739#define F_OK 0
740#endif
741#ifndef R_OK
742#define R_OK 4
743#endif
744#ifndef W_OK
745#define W_OK 2
746#endif
747#ifndef X_OK
748#define X_OK 1
749#endif
750
751#ifdef HAVE_TTYNAME
Guido van Rossum94f6f721999-01-06 18:42:14 +0000752static char posix_ttyname__doc__[] =
Guido van Rossum61eeb041999-02-22 15:29:15 +0000753"ttyname(fd) -> String\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +0000754Return the name of the terminal device connected to 'fd'.";
755
756static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000757posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000758{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000759 int id;
760 char *ret;
761
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000762 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000763 return NULL;
764
Guido van Rossum94f6f721999-01-06 18:42:14 +0000765 ret = ttyname(id);
766 if (ret == NULL)
767 return(posix_error());
768 return(PyString_FromString(ret));
769}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000770#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000771
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000772#ifdef HAVE_CTERMID
773static char posix_ctermid__doc__[] =
774"ctermid() -> String\n\
775Return the name of the controlling terminal for this process.";
776
777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000778posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000779{
780 char *ret;
781 char buffer[L_ctermid];
782
783 if (!PyArg_ParseTuple(args, ":ctermid"))
784 return NULL;
785
Greg Wardb48bc172000-03-01 21:51:56 +0000786#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000787 ret = ctermid_r(buffer);
788#else
789 ret = ctermid(buffer);
790#endif
791 if (ret == NULL)
792 return(posix_error());
793 return(PyString_FromString(buffer));
794}
795#endif
796
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000797static char posix_chdir__doc__[] =
798"chdir(path) -> None\n\
799Change the current working directory to the specified path.";
800
Barry Warsaw53699e91996-12-10 23:23:01 +0000801static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000802posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000803{
Mark Hammondef8b6542001-05-13 08:04:26 +0000804 return posix_1str(args, "et:chdir", chdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000805}
806
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000807
808static char posix_chmod__doc__[] =
809"chmod(path, mode) -> None\n\
810Change the access permissions of a file.";
811
Barry Warsaw53699e91996-12-10 23:23:01 +0000812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000813posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000814{
Mark Hammondef8b6542001-05-13 08:04:26 +0000815 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000816 int i;
817 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000818 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000819 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000820 return NULL;
821 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000822 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000823 Py_END_ALLOW_THREADS
824 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000825 return posix_error_with_allocated_filename(path);
826 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000827 Py_INCREF(Py_None);
828 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000829}
830
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000831
Martin v. Löwis244edc82001-10-04 22:44:26 +0000832#ifdef HAVE_CHROOT
Tim Peters5aa91602002-01-30 05:46:57 +0000833static char posix_chroot__doc__[] =
Martin v. Löwis244edc82001-10-04 22:44:26 +0000834"chroot(path) -> None\n\
835Change root directory to path.";
836
837static PyObject *
838posix_chroot(PyObject *self, PyObject *args)
839{
840 return posix_1str(args, "et:chroot", chroot);
841}
842#endif
843
Guido van Rossum21142a01999-01-08 21:05:37 +0000844#ifdef HAVE_FSYNC
845static char posix_fsync__doc__[] =
846"fsync(fildes) -> None\n\
847force write of file with filedescriptor to disk.";
848
849static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000850posix_fsync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000851{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000852 return posix_int(args, "i:fsync", fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000853}
854#endif /* HAVE_FSYNC */
855
856#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000857
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000858#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000859extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
860#endif
861
Guido van Rossum21142a01999-01-08 21:05:37 +0000862static char posix_fdatasync__doc__[] =
863"fdatasync(fildes) -> None\n\
864force write of file with filedescriptor to disk.\n\
865 does not force update of metadata.";
866
867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000868posix_fdatasync(PyObject *self, PyObject *args)
Guido van Rossum21142a01999-01-08 21:05:37 +0000869{
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000870 return posix_int(args, "i:fdatasync", fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000871}
872#endif /* HAVE_FDATASYNC */
873
874
Fredrik Lundh10723342000-07-10 16:38:09 +0000875#ifdef HAVE_CHOWN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000876static char posix_chown__doc__[] =
877"chown(path, uid, gid) -> None\n\
878Change the owner and group id of path to the numeric uid and gid.";
879
Barry Warsaw53699e91996-12-10 23:23:01 +0000880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000881posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000882{
Mark Hammondef8b6542001-05-13 08:04:26 +0000883 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000884 int uid, gid;
885 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000886 if (!PyArg_ParseTuple(args, "etii:chown",
887 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000888 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000889 return NULL;
890 Py_BEGIN_ALLOW_THREADS
891 res = chown(path, (uid_t) uid, (gid_t) gid);
892 Py_END_ALLOW_THREADS
893 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000894 return posix_error_with_allocated_filename(path);
895 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000896 Py_INCREF(Py_None);
897 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000898}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000899#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000901
Guido van Rossum36bc6801995-06-14 22:54:23 +0000902#ifdef HAVE_GETCWD
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000903static char posix_getcwd__doc__[] =
904"getcwd() -> path\n\
905Return a string representing the current working directory.";
906
Barry Warsaw53699e91996-12-10 23:23:01 +0000907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000908posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000909{
910 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000911 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000912 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000913 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000914 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000915 res = getcwd(buf, sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +0000916 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000917 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000918 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000919 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000920}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000921#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000922
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000923
Guido van Rossumb6775db1994-08-01 11:34:53 +0000924#ifdef HAVE_LINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000925static char posix_link__doc__[] =
926"link(src, dst) -> None\n\
927Create a hard link to a file.";
928
Barry Warsaw53699e91996-12-10 23:23:01 +0000929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000930posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000931{
Mark Hammondef8b6542001-05-13 08:04:26 +0000932 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000933}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000934#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000935
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000936
937static char posix_listdir__doc__[] =
938"listdir(path) -> list_of_strings\n\
939Return a list containing the names of the entries in the directory.\n\
940\n\
941 path: path of directory to list\n\
942\n\
943The list is in arbitrary order. It does not include the special\n\
944entries '.' and '..' even if they are present in the directory.";
945
Barry Warsaw53699e91996-12-10 23:23:01 +0000946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000947posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000948{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000949 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000950 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000951#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000952
Barry Warsaw53699e91996-12-10 23:23:01 +0000953 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000954 HANDLE hFindFile;
955 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000956 /* MAX_PATH characters could mean a bigger encoded string */
957 char namebuf[MAX_PATH*2+5];
958 char *bufptr = namebuf;
959 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Tim Peters0bb44a42000-09-15 07:44:49 +0000960 char ch;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000961
Tim Peters5aa91602002-01-30 05:46:57 +0000962 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +0000963 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000964 return NULL;
Tim Peters0bb44a42000-09-15 07:44:49 +0000965 ch = namebuf[len-1];
966 if (ch != '/' && ch != '\\' && ch != ':')
Guido van Rossumb6775db1994-08-01 11:34:53 +0000967 namebuf[len++] = '/';
968 strcpy(namebuf + len, "*.*");
969
Barry Warsaw53699e91996-12-10 23:23:01 +0000970 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000971 return NULL;
972
973 hFindFile = FindFirstFile(namebuf, &FileData);
974 if (hFindFile == INVALID_HANDLE_VALUE) {
975 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +0000976 if (errno == ERROR_FILE_NOT_FOUND)
977 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +0000978 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000979 }
980 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +0000981 if (FileData.cFileName[0] == '.' &&
982 (FileData.cFileName[1] == '\0' ||
983 FileData.cFileName[1] == '.' &&
984 FileData.cFileName[2] == '\0'))
985 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +0000986 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000987 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +0000988 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000989 d = NULL;
990 break;
991 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000992 if (PyList_Append(d, v) != 0) {
993 Py_DECREF(v);
994 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000995 d = NULL;
996 break;
997 }
Barry Warsaw53699e91996-12-10 23:23:01 +0000998 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000999 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1000
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001001 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001002 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001003
1004 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001005
Tim Peters0bb44a42000-09-15 07:44:49 +00001006#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001007
1008#ifndef MAX_PATH
1009#define MAX_PATH 250
1010#endif
1011 char *name, *pt;
1012 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001013 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001014 char namebuf[MAX_PATH+5];
1015 struct _find_t ep;
1016
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001017 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001018 return NULL;
1019 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001020 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001021 return NULL;
1022 }
1023 strcpy(namebuf, name);
1024 for (pt = namebuf; *pt; pt++)
1025 if (*pt == '/')
1026 *pt = '\\';
1027 if (namebuf[len-1] != '\\')
1028 namebuf[len++] = '\\';
1029 strcpy(namebuf + len, "*.*");
1030
Barry Warsaw53699e91996-12-10 23:23:01 +00001031 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001032 return NULL;
1033
1034 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001035 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1036 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001037 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001038 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001039 }
1040 do {
1041 if (ep.name[0] == '.' &&
1042 (ep.name[1] == '\0' ||
1043 ep.name[1] == '.' &&
1044 ep.name[2] == '\0'))
1045 continue;
1046 strcpy(namebuf, ep.name);
1047 for (pt = namebuf; *pt; pt++)
1048 if (isupper(*pt))
1049 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001050 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001051 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001052 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001053 d = NULL;
1054 break;
1055 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001056 if (PyList_Append(d, v) != 0) {
1057 Py_DECREF(v);
1058 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001059 d = NULL;
1060 break;
1061 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001062 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001063 } while (_dos_findnext(&ep) == 0);
1064
1065 return d;
1066
Tim Peters0bb44a42000-09-15 07:44:49 +00001067#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001068
1069#ifndef MAX_PATH
1070#define MAX_PATH CCHMAXPATH
1071#endif
1072 char *name, *pt;
1073 int len;
1074 PyObject *d, *v;
1075 char namebuf[MAX_PATH+5];
1076 HDIR hdir = 1;
1077 ULONG srchcnt = 1;
1078 FILEFINDBUF3 ep;
1079 APIRET rc;
1080
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001081 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001082 return NULL;
1083 if (len >= MAX_PATH) {
1084 PyErr_SetString(PyExc_ValueError, "path too long");
1085 return NULL;
1086 }
1087 strcpy(namebuf, name);
1088 for (pt = namebuf; *pt; pt++)
1089 if (*pt == '/')
1090 *pt = '\\';
1091 if (namebuf[len-1] != '\\')
1092 namebuf[len++] = '\\';
1093 strcpy(namebuf + len, "*.*");
1094
1095 if ((d = PyList_New(0)) == NULL)
1096 return NULL;
1097
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001098 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1099 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001100 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001101 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1102 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1103 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001104
1105 if (rc != NO_ERROR) {
1106 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001107 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001108 }
1109
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001110 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001111 do {
1112 if (ep.achName[0] == '.'
1113 && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001114 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001115
1116 strcpy(namebuf, ep.achName);
1117
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001118 /* Leave Case of Name Alone -- In Native Form */
1119 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001120
1121 v = PyString_FromString(namebuf);
1122 if (v == NULL) {
1123 Py_DECREF(d);
1124 d = NULL;
1125 break;
1126 }
1127 if (PyList_Append(d, v) != 0) {
1128 Py_DECREF(v);
1129 Py_DECREF(d);
1130 d = NULL;
1131 break;
1132 }
1133 Py_DECREF(v);
1134 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1135 }
1136
1137 return d;
1138#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001139
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001140 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001141 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001143 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001144 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001145 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001146 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001147 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001148 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001149 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001150 closedir(dirp);
1151 return NULL;
1152 }
1153 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001154 if (ep->d_name[0] == '.' &&
1155 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001156 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001157 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001158 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001159 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001160 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001161 d = NULL;
1162 break;
1163 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001164 if (PyList_Append(d, v) != 0) {
1165 Py_DECREF(v);
1166 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001167 d = NULL;
1168 break;
1169 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001170 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171 }
1172 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001173
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001174 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001175
Tim Peters0bb44a42000-09-15 07:44:49 +00001176#endif /* which OS */
1177} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178
Mark Hammondef8b6542001-05-13 08:04:26 +00001179#ifdef MS_WIN32
1180/* A helper function for abspath on win32 */
1181static PyObject *
1182posix__getfullpathname(PyObject *self, PyObject *args)
1183{
1184 /* assume encoded strings wont more than double no of chars */
1185 char inbuf[MAX_PATH*2];
1186 char *inbufp = inbuf;
1187 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1188 char outbuf[MAX_PATH*2];
1189 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001190 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1191 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001192 &insize))
1193 return NULL;
1194 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1195 outbuf, &temp))
1196 return win32_error("GetFullPathName", inbuf);
1197 return PyString_FromString(outbuf);
1198} /* end of posix__getfullpathname */
1199#endif /* MS_WIN32 */
1200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001201static char posix_mkdir__doc__[] =
1202"mkdir(path [, mode=0777]) -> None\n\
1203Create a directory.";
1204
Barry Warsaw53699e91996-12-10 23:23:01 +00001205static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001206posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001207{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001208 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001209 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001210 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001211 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001212 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001213 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001214 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001215#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001216 res = mkdir(path);
1217#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001218 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001219#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001220 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001221 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001222 return posix_error_with_allocated_filename(path);
1223 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001224 Py_INCREF(Py_None);
1225 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226}
1227
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001228
Guido van Rossumb6775db1994-08-01 11:34:53 +00001229#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001230#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1231#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1232#include <sys/resource.h>
1233#endif
1234#endif
1235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001236static char posix_nice__doc__[] =
1237"nice(inc) -> new_priority\n\
1238Decrease the priority of process and return new priority.";
1239
Barry Warsaw53699e91996-12-10 23:23:01 +00001240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001241posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001242{
1243 int increment, value;
1244
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001245 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001246 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001247
1248 /* There are two flavours of 'nice': one that returns the new
1249 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001250 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1251 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001252
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001253 If we are of the nice family that returns the new priority, we
1254 need to clear errno before the call, and check if errno is filled
1255 before calling posix_error() on a returnvalue of -1, because the
1256 -1 may be the actual new priority! */
1257
1258 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001259 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001260#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001261 if (value == 0)
1262 value = getpriority(PRIO_PROCESS, 0);
1263#endif
1264 if (value == -1 && errno != 0)
1265 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001266 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001267 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001268}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001269#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001271
1272static char posix_rename__doc__[] =
1273"rename(old, new) -> None\n\
1274Rename a file or directory.";
1275
Barry Warsaw53699e91996-12-10 23:23:01 +00001276static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001277posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001278{
Mark Hammondef8b6542001-05-13 08:04:26 +00001279 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001280}
1281
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001282
1283static char posix_rmdir__doc__[] =
1284"rmdir(path) -> None\n\
1285Remove a directory.";
1286
Barry Warsaw53699e91996-12-10 23:23:01 +00001287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001288posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001289{
Mark Hammondef8b6542001-05-13 08:04:26 +00001290 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001291}
1292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001293
1294static char posix_stat__doc__[] =
1295"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1296Perform a stat system call on the given path.";
1297
Barry Warsaw53699e91996-12-10 23:23:01 +00001298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001299posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001300{
Mark Hammondef8b6542001-05-13 08:04:26 +00001301 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001302}
1303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001304
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001305#ifdef HAVE_SYSTEM
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001306static char posix_system__doc__[] =
1307"system(command) -> exit_status\n\
1308Execute the command (a string) in a subshell.";
1309
Barry Warsaw53699e91996-12-10 23:23:01 +00001310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001311posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001312{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001313 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001314 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001315 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001316 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001317 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001318 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001319 Py_END_ALLOW_THREADS
1320 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001321}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001322#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001324
1325static char posix_umask__doc__[] =
1326"umask(new_mask) -> old_mask\n\
1327Set the current numeric umask and return the previous umask.";
1328
Barry Warsaw53699e91996-12-10 23:23:01 +00001329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001330posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001331{
1332 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001333 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001334 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001335 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001336 if (i < 0)
1337 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001338 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001339}
1340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001341
1342static char posix_unlink__doc__[] =
1343"unlink(path) -> None\n\
1344Remove a file (same as remove(path)).";
1345
1346static char posix_remove__doc__[] =
1347"remove(path) -> None\n\
1348Remove a file (same as unlink(path)).";
1349
Barry Warsaw53699e91996-12-10 23:23:01 +00001350static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001351posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001352{
Mark Hammondef8b6542001-05-13 08:04:26 +00001353 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001354}
1355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001356
Guido van Rossumb6775db1994-08-01 11:34:53 +00001357#ifdef HAVE_UNAME
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001358static char posix_uname__doc__[] =
1359"uname() -> (sysname, nodename, release, version, machine)\n\
1360Return a tuple identifying the current operating system.";
1361
Barry Warsaw53699e91996-12-10 23:23:01 +00001362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001363posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001364{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001365 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001366 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001367 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001368 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001369 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001370 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001371 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001372 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001373 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001374 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001375 u.sysname,
1376 u.nodename,
1377 u.release,
1378 u.version,
1379 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001380}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001381#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001382
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001383
1384static char posix_utime__doc__[] =
1385"utime(path, (atime, utime)) -> None\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001386utime(path, None) -> None\n\
1387Set the access and modified time of the file to the given values. If the\n\
1388second form is used, set the access and modified times to the current time.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001389
Barry Warsaw53699e91996-12-10 23:23:01 +00001390static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001391posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001393 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001394 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001395 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001396 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001397
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001398/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001399#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001400 struct utimbuf buf;
1401#define ATIME buf.actime
1402#define MTIME buf.modtime
1403#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001404#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001405 time_t buf[2];
1406#define ATIME buf[0]
1407#define MTIME buf[1]
1408#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001409#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001410
Barry Warsaw3cef8562000-05-01 16:17:24 +00001411 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001412 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001413 if (arg == Py_None) {
1414 /* optional time values not given */
1415 Py_BEGIN_ALLOW_THREADS
1416 res = utime(path, NULL);
1417 Py_END_ALLOW_THREADS
1418 }
1419 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1420 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001421 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001422 return NULL;
1423 }
1424 else {
1425 ATIME = atime;
1426 MTIME = mtime;
1427 Py_BEGIN_ALLOW_THREADS
1428 res = utime(path, UTIME_ARG);
1429 Py_END_ALLOW_THREADS
1430 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001431 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001432 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001433 Py_INCREF(Py_None);
1434 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001435#undef UTIME_ARG
1436#undef ATIME
1437#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001438}
1439
Guido van Rossum85e3b011991-06-03 12:42:10 +00001440
Guido van Rossum3b066191991-06-04 19:40:25 +00001441/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001442
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001443static char posix__exit__doc__[] =
1444"_exit(status)\n\
1445Exit to the system with specified status, without normal exit processing.";
1446
Barry Warsaw53699e91996-12-10 23:23:01 +00001447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001448posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001449{
1450 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001451 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001452 return NULL;
1453 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001454 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001455}
1456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001457
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001458#ifdef HAVE_EXECV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001459static char posix_execv__doc__[] =
1460"execv(path, args)\n\
1461Execute an executable path with arguments, replacing current process.\n\
1462\n\
1463 path: path of executable file\n\
1464 args: tuple or list of strings";
1465
Barry Warsaw53699e91996-12-10 23:23:01 +00001466static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001467posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001468{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001469 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001470 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001471 char **argvlist;
1472 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001473 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001474
Guido van Rossum89b33251993-10-22 14:26:06 +00001475 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001476 argv is a list or tuple of strings. */
1477
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001478 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001479 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001480 if (PyList_Check(argv)) {
1481 argc = PyList_Size(argv);
1482 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001483 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001484 else if (PyTuple_Check(argv)) {
1485 argc = PyTuple_Size(argv);
1486 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001487 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001488 else {
Fred Drake661ea262000-10-24 19:57:45 +00001489 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001490 return NULL;
1491 }
1492
1493 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001494 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001495 return NULL;
1496 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001497
Barry Warsaw53699e91996-12-10 23:23:01 +00001498 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001499 if (argvlist == NULL)
1500 return NULL;
1501 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001502 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1503 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001504 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001505 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001506 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001507
Guido van Rossum85e3b011991-06-03 12:42:10 +00001508 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001509 }
1510 argvlist[argc] = NULL;
1511
Guido van Rossumb6775db1994-08-01 11:34:53 +00001512#ifdef BAD_EXEC_PROTOTYPES
1513 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001514#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001515 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001516#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001517
Guido van Rossum85e3b011991-06-03 12:42:10 +00001518 /* If we get here it's definitely an error */
1519
Barry Warsaw53699e91996-12-10 23:23:01 +00001520 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001521 return posix_error();
1522}
1523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001524
1525static char posix_execve__doc__[] =
1526"execve(path, args, env)\n\
1527Execute a path with arguments and environment, replacing current process.\n\
1528\n\
1529 path: path of executable file\n\
1530 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001531 env: dictionary of strings mapping to strings";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001532
Barry Warsaw53699e91996-12-10 23:23:01 +00001533static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001534posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001535{
1536 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001537 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001538 char **argvlist;
1539 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001540 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001541 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001542 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001543
1544 /* execve has three arguments: (path, argv, env), where
1545 argv is a list or tuple of strings and env is a dictionary
1546 like posix.environ. */
1547
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001548 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001549 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001550 if (PyList_Check(argv)) {
1551 argc = PyList_Size(argv);
1552 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001553 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001554 else if (PyTuple_Check(argv)) {
1555 argc = PyTuple_Size(argv);
1556 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001557 }
1558 else {
Fred Drake661ea262000-10-24 19:57:45 +00001559 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001560 return NULL;
1561 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001562 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001563 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001564 return NULL;
1565 }
1566
Guido van Rossum50422b42000-04-26 20:34:28 +00001567 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001568 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001569 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001570 return NULL;
1571 }
1572
Barry Warsaw53699e91996-12-10 23:23:01 +00001573 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001574 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001575 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001576 return NULL;
1577 }
1578 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001579 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001580 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001581 &argvlist[i]))
1582 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001583 goto fail_1;
1584 }
1585 }
1586 argvlist[argc] = NULL;
1587
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001588 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001589 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001590 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001591 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001592 goto fail_1;
1593 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001594 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001595 keys = PyMapping_Keys(env);
1596 vals = PyMapping_Values(env);
1597 if (!keys || !vals)
1598 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001599
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001600 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001602 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001603
1604 key = PyList_GetItem(keys, pos);
1605 val = PyList_GetItem(vals, pos);
1606 if (!key || !val)
1607 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001608
Fred Drake661ea262000-10-24 19:57:45 +00001609 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1610 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001611 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001612 goto fail_2;
1613 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001614
1615#if defined(PYOS_OS2)
1616 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1617 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1618#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001619 len = PyString_Size(key) + PyString_Size(val) + 2;
1620 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001621 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001622 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001623 goto fail_2;
1624 }
Tim Petersc8996f52001-12-03 20:41:00 +00001625 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001626 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001627#if defined(PYOS_OS2)
1628 }
1629#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001630 }
1631 envlist[envc] = 0;
1632
Guido van Rossumb6775db1994-08-01 11:34:53 +00001633
1634#ifdef BAD_EXEC_PROTOTYPES
1635 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001636#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001637 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001638#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001639
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001640 /* If we get here it's definitely an error */
1641
1642 (void) posix_error();
1643
1644 fail_2:
1645 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001646 PyMem_DEL(envlist[envc]);
1647 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001648 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001649 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001650 Py_XDECREF(vals);
1651 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001652 return NULL;
1653}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001654#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001655
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001656
Guido van Rossuma1065681999-01-25 23:20:23 +00001657#ifdef HAVE_SPAWNV
1658static char posix_spawnv__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001659"spawnv(mode, path, args)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001660Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001661\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001662 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001663 path: path of executable file\n\
1664 args: tuple or list of strings";
1665
1666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001667posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001668{
1669 char *path;
1670 PyObject *argv;
1671 char **argvlist;
1672 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001673 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001674 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001675
1676 /* spawnv has three arguments: (mode, path, argv), where
1677 argv is a list or tuple of strings. */
1678
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001679 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001680 return NULL;
1681 if (PyList_Check(argv)) {
1682 argc = PyList_Size(argv);
1683 getitem = PyList_GetItem;
1684 }
1685 else if (PyTuple_Check(argv)) {
1686 argc = PyTuple_Size(argv);
1687 getitem = PyTuple_GetItem;
1688 }
1689 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001690 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001691 return NULL;
1692 }
1693
1694 argvlist = PyMem_NEW(char *, argc+1);
1695 if (argvlist == NULL)
1696 return NULL;
1697 for (i = 0; i < argc; i++) {
1698 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1699 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001700 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001701 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001702 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001703 }
1704 }
1705 argvlist[argc] = NULL;
1706
Guido van Rossum246bc171999-02-01 23:54:31 +00001707 if (mode == _OLD_P_OVERLAY)
1708 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001709
Tim Peters25059d32001-12-07 20:35:43 +00001710 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001711 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001712 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00001713
Guido van Rossuma1065681999-01-25 23:20:23 +00001714 PyMem_DEL(argvlist);
1715
Fred Drake699f3522000-06-29 21:12:41 +00001716 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001717 return posix_error();
1718 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001719#if SIZEOF_LONG == SIZEOF_VOID_P
1720 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001721#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001722 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001723#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001724}
1725
1726
1727static char posix_spawnve__doc__[] =
Fred Drakea6dff3e1999-02-01 22:24:40 +00001728"spawnve(mode, path, args, env)\n\
Tim Peters25059d32001-12-07 20:35:43 +00001729Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001730\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001731 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001732 path: path of executable file\n\
1733 args: tuple or list of arguments\n\
Thomas Wouters7e474022000-07-16 12:04:32 +00001734 env: dictionary of strings mapping to strings";
Guido van Rossuma1065681999-01-25 23:20:23 +00001735
1736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001737posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001738{
1739 char *path;
1740 PyObject *argv, *env;
1741 char **argvlist;
1742 char **envlist;
1743 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1744 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001745 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001746 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001747
1748 /* spawnve has four arguments: (mode, path, argv, env), where
1749 argv is a list or tuple of strings and env is a dictionary
1750 like posix.environ. */
1751
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001752 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001753 return NULL;
1754 if (PyList_Check(argv)) {
1755 argc = PyList_Size(argv);
1756 getitem = PyList_GetItem;
1757 }
1758 else if (PyTuple_Check(argv)) {
1759 argc = PyTuple_Size(argv);
1760 getitem = PyTuple_GetItem;
1761 }
1762 else {
Fred Drake661ea262000-10-24 19:57:45 +00001763 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001764 return NULL;
1765 }
1766 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001767 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001768 return NULL;
1769 }
1770
1771 argvlist = PyMem_NEW(char *, argc+1);
1772 if (argvlist == NULL) {
1773 PyErr_NoMemory();
1774 return NULL;
1775 }
1776 for (i = 0; i < argc; i++) {
1777 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001778 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001779 &argvlist[i]))
1780 {
1781 goto fail_1;
1782 }
1783 }
1784 argvlist[argc] = NULL;
1785
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001786 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001787 envlist = PyMem_NEW(char *, i + 1);
1788 if (envlist == NULL) {
1789 PyErr_NoMemory();
1790 goto fail_1;
1791 }
1792 envc = 0;
1793 keys = PyMapping_Keys(env);
1794 vals = PyMapping_Values(env);
1795 if (!keys || !vals)
1796 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001797
Guido van Rossuma1065681999-01-25 23:20:23 +00001798 for (pos = 0; pos < i; pos++) {
1799 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001800 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001801
1802 key = PyList_GetItem(keys, pos);
1803 val = PyList_GetItem(vals, pos);
1804 if (!key || !val)
1805 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001806
Fred Drake661ea262000-10-24 19:57:45 +00001807 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1808 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001809 {
1810 goto fail_2;
1811 }
Tim Petersc8996f52001-12-03 20:41:00 +00001812 len = PyString_Size(key) + PyString_Size(val) + 2;
1813 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001814 if (p == NULL) {
1815 PyErr_NoMemory();
1816 goto fail_2;
1817 }
Tim Petersc8996f52001-12-03 20:41:00 +00001818 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001819 envlist[envc++] = p;
1820 }
1821 envlist[envc] = 0;
1822
Guido van Rossum246bc171999-02-01 23:54:31 +00001823 if (mode == _OLD_P_OVERLAY)
1824 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001825
1826 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001827 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001828 Py_END_ALLOW_THREADS
1829
Fred Drake699f3522000-06-29 21:12:41 +00001830 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001831 (void) posix_error();
1832 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001833#if SIZEOF_LONG == SIZEOF_VOID_P
1834 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001835#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001836 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001837#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001838
1839 fail_2:
1840 while (--envc >= 0)
1841 PyMem_DEL(envlist[envc]);
1842 PyMem_DEL(envlist);
1843 fail_1:
1844 PyMem_DEL(argvlist);
1845 Py_XDECREF(vals);
1846 Py_XDECREF(keys);
1847 return res;
1848}
1849#endif /* HAVE_SPAWNV */
1850
1851
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001852#ifdef HAVE_FORK1
1853static char posix_fork1__doc__[] =
1854"fork1() -> pid\n\
1855Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1856\n\
1857Return 0 to child process and PID of child to parent process.";
1858
1859static PyObject *
1860posix_fork1(self, args)
1861 PyObject *self;
1862 PyObject *args;
1863{
1864 int pid;
1865 if (!PyArg_ParseTuple(args, ":fork1"))
1866 return NULL;
1867 pid = fork1();
1868 if (pid == -1)
1869 return posix_error();
1870 PyOS_AfterFork();
1871 return PyInt_FromLong((long)pid);
1872}
1873#endif
1874
1875
Guido van Rossumad0ee831995-03-01 10:34:45 +00001876#ifdef HAVE_FORK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001877static char posix_fork__doc__[] =
1878"fork() -> pid\n\
1879Fork a child process.\n\
1880\n\
1881Return 0 to child process and PID of child to parent process.";
1882
Barry Warsaw53699e91996-12-10 23:23:01 +00001883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001884posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001885{
1886 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001887 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001888 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001889 pid = fork();
1890 if (pid == -1)
1891 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001892 if (pid == 0)
1893 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001894 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001895}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001896#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001897
Fred Drake8cef4cf2000-06-28 16:40:38 +00001898#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1899#ifdef HAVE_PTY_H
1900#include <pty.h>
1901#else
1902#ifdef HAVE_LIBUTIL_H
1903#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001904#endif /* HAVE_LIBUTIL_H */
1905#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001906#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001907
Thomas Wouters70c21a12000-07-14 14:28:33 +00001908#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001909static char posix_openpty__doc__[] =
1910"openpty() -> (master_fd, slave_fd)\n\
1911Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1912
1913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001914posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001915{
1916 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001917#ifndef HAVE_OPENPTY
1918 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001919#endif
1920
Fred Drake8cef4cf2000-06-28 16:40:38 +00001921 if (!PyArg_ParseTuple(args, ":openpty"))
1922 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001923
1924#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001925 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1926 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001927#else
1928 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1929 if (slave_name == NULL)
1930 return posix_error();
1931
1932 slave_fd = open(slave_name, O_RDWR);
1933 if (slave_fd < 0)
1934 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001935#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001936
Fred Drake8cef4cf2000-06-28 16:40:38 +00001937 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001938
Fred Drake8cef4cf2000-06-28 16:40:38 +00001939}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001940#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001941
1942#ifdef HAVE_FORKPTY
1943static char posix_forkpty__doc__[] =
1944"forkpty() -> (pid, master_fd)\n\
1945Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1946Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1947To both, return fd of newly opened pseudo-terminal.\n";
1948
1949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001950posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001951{
1952 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00001953
Fred Drake8cef4cf2000-06-28 16:40:38 +00001954 if (!PyArg_ParseTuple(args, ":forkpty"))
1955 return NULL;
1956 pid = forkpty(&master_fd, NULL, NULL, NULL);
1957 if (pid == -1)
1958 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001959 if (pid == 0)
1960 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00001961 return Py_BuildValue("(ii)", pid, master_fd);
1962}
1963#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001964
Guido van Rossumad0ee831995-03-01 10:34:45 +00001965#ifdef HAVE_GETEGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001966static char posix_getegid__doc__[] =
1967"getegid() -> egid\n\
1968Return the current process's effective group id.";
1969
Barry Warsaw53699e91996-12-10 23:23:01 +00001970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001971posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001972{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001973 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001974 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001975 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001976}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001977#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001979
Guido van Rossumad0ee831995-03-01 10:34:45 +00001980#ifdef HAVE_GETEUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001981static char posix_geteuid__doc__[] =
1982"geteuid() -> euid\n\
1983Return the current process's effective user id.";
1984
Barry Warsaw53699e91996-12-10 23:23:01 +00001985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001986posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00001987{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001988 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00001989 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001990 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00001991}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001992#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00001993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001994
Guido van Rossumad0ee831995-03-01 10:34:45 +00001995#ifdef HAVE_GETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001996static char posix_getgid__doc__[] =
1997"getgid() -> gid\n\
1998Return the current process's group id.";
1999
Barry Warsaw53699e91996-12-10 23:23:01 +00002000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002001posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002002{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002003 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002004 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002005 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002006}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002007#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002009
2010static char posix_getpid__doc__[] =
2011"getpid() -> pid\n\
2012Return the current process id";
2013
Barry Warsaw53699e91996-12-10 23:23:01 +00002014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002015posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002016{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002017 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002018 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002019 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002020}
2021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002022
Fred Drakec9680921999-12-13 16:37:25 +00002023#ifdef HAVE_GETGROUPS
2024static char posix_getgroups__doc__[] = "\
2025getgroups() -> list of group IDs\n\
2026Return list of supplemental group IDs for the process.";
2027
2028static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002029posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002030{
2031 PyObject *result = NULL;
2032
2033 if (PyArg_ParseTuple(args, ":getgroups")) {
2034#ifdef NGROUPS_MAX
2035#define MAX_GROUPS NGROUPS_MAX
2036#else
2037 /* defined to be 16 on Solaris7, so this should be a small number */
2038#define MAX_GROUPS 64
2039#endif
2040 gid_t grouplist[MAX_GROUPS];
2041 int n;
2042
2043 n = getgroups(MAX_GROUPS, grouplist);
2044 if (n < 0)
2045 posix_error();
2046 else {
2047 result = PyList_New(n);
2048 if (result != NULL) {
2049 PyObject *o;
2050 int i;
2051 for (i = 0; i < n; ++i) {
2052 o = PyInt_FromLong((long)grouplist[i]);
2053 if (o == NULL) {
2054 Py_DECREF(result);
2055 result = NULL;
2056 break;
2057 }
2058 PyList_SET_ITEM(result, i, o);
2059 }
2060 }
2061 }
2062 }
2063 return result;
2064}
2065#endif
2066
Guido van Rossumb6775db1994-08-01 11:34:53 +00002067#ifdef HAVE_GETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068static char posix_getpgrp__doc__[] =
2069"getpgrp() -> pgrp\n\
2070Return the current process group id.";
2071
Barry Warsaw53699e91996-12-10 23:23:01 +00002072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002073posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002074{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002075 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002076 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002077#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002078 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002079#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002080 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002081#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002082}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002083#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002085
Guido van Rossumb6775db1994-08-01 11:34:53 +00002086#ifdef HAVE_SETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087static char posix_setpgrp__doc__[] =
2088"setpgrp() -> None\n\
2089Make this process a session leader.";
2090
Barry Warsaw53699e91996-12-10 23:23:01 +00002091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002092posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002093{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002094 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002095 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002096#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002097 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002098#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002099 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002100#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002101 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002102 Py_INCREF(Py_None);
2103 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002104}
2105
Guido van Rossumb6775db1994-08-01 11:34:53 +00002106#endif /* HAVE_SETPGRP */
2107
Guido van Rossumad0ee831995-03-01 10:34:45 +00002108#ifdef HAVE_GETPPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002109static char posix_getppid__doc__[] =
2110"getppid() -> ppid\n\
2111Return the parent's process id.";
2112
Barry Warsaw53699e91996-12-10 23:23:01 +00002113static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002114posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002115{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002116 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002117 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002118 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002119}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002120#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122
Fred Drake12c6e2d1999-12-14 21:25:03 +00002123#ifdef HAVE_GETLOGIN
2124static char posix_getlogin__doc__[] = "\
2125getlogin() -> string\n\
2126Return the actual login name.";
2127
2128static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002129posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002130{
2131 PyObject *result = NULL;
2132
2133 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002134 char *name;
2135 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002136
Fred Drakea30680b2000-12-06 21:24:28 +00002137 errno = 0;
2138 name = getlogin();
2139 if (name == NULL) {
2140 if (errno)
2141 posix_error();
2142 else
2143 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002144 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002145 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002146 else
2147 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002148 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002149 }
2150 return result;
2151}
2152#endif
2153
Guido van Rossumad0ee831995-03-01 10:34:45 +00002154#ifdef HAVE_GETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002155static char posix_getuid__doc__[] =
2156"getuid() -> uid\n\
2157Return the current process's user id.";
2158
Barry Warsaw53699e91996-12-10 23:23:01 +00002159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002160posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002161{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002162 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002163 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002164 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002165}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002166#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002167
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002168
Guido van Rossumad0ee831995-03-01 10:34:45 +00002169#ifdef HAVE_KILL
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002170static char posix_kill__doc__[] =
2171"kill(pid, sig) -> None\n\
2172Kill a process with a signal.";
2173
Barry Warsaw53699e91996-12-10 23:23:01 +00002174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002175posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002176{
2177 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002178 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002179 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002180#if defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002181 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2182 APIRET rc;
2183 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002184 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002185
2186 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2187 APIRET rc;
2188 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002189 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002190
2191 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002192 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002193#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002194 if (kill(pid, sig) == -1)
2195 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002196#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002197 Py_INCREF(Py_None);
2198 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002199}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002200#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002201
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002202#ifdef HAVE_KILLPG
2203static char posix_killpg__doc__[] =
2204"killpg(pgid, sig) -> None\n\
2205Kill a process group with a signal.";
2206
2207static PyObject *
2208posix_killpg(PyObject *self, PyObject *args)
2209{
2210 int pgid, sig;
2211 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2212 return NULL;
2213 if (killpg(pgid, sig) == -1)
2214 return posix_error();
2215 Py_INCREF(Py_None);
2216 return Py_None;
2217}
2218#endif
2219
Guido van Rossumc0125471996-06-28 18:55:32 +00002220#ifdef HAVE_PLOCK
2221
2222#ifdef HAVE_SYS_LOCK_H
2223#include <sys/lock.h>
2224#endif
2225
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002226static char posix_plock__doc__[] =
2227"plock(op) -> None\n\
2228Lock program segments into memory.";
2229
Barry Warsaw53699e91996-12-10 23:23:01 +00002230static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002231posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002232{
2233 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002234 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002235 return NULL;
2236 if (plock(op) == -1)
2237 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002238 Py_INCREF(Py_None);
2239 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002240}
2241#endif
2242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002243
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002244#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002245static char posix_popen__doc__[] =
2246"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2247Open a pipe to/from a command returning a file object.";
2248
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002249#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002250static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002251async_system(const char *command)
2252{
2253 char *p, errormsg[256], args[1024];
2254 RESULTCODES rcodes;
2255 APIRET rc;
2256 char *shell = getenv("COMSPEC");
2257 if (!shell)
2258 shell = "cmd";
2259
2260 strcpy(args, shell);
2261 p = &args[ strlen(args)+1 ];
2262 strcpy(p, "/c ");
2263 strcat(p, command);
2264 p += strlen(p) + 1;
2265 *p = '\0';
2266
2267 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002268 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002269 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002270 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002271 &rcodes, shell);
2272 return rc;
2273}
2274
Guido van Rossumd48f2521997-12-05 22:19:34 +00002275static FILE *
2276popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002277{
2278 HFILE rhan, whan;
2279 FILE *retfd = NULL;
2280 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2281
Guido van Rossumd48f2521997-12-05 22:19:34 +00002282 if (rc != NO_ERROR) {
2283 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002284 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002285 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002286
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002287 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2288 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002289
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002290 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2291 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002292
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002293 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2294 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002295
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002296 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002297 }
2298
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002299 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2300 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002301
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002302 if (rc == NO_ERROR)
2303 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2304
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002305 close(oldfd); /* And Close Saved STDOUT Handle */
2306 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002307
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002308 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2309 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002310
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002311 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2312 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002313
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002314 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2315 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002316
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002317 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002318 }
2319
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002320 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2321 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002322
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002323 if (rc == NO_ERROR)
2324 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2325
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002326 close(oldfd); /* And Close Saved STDIN Handle */
2327 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002328
Guido van Rossumd48f2521997-12-05 22:19:34 +00002329 } else {
2330 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002331 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002332 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002333}
2334
2335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002336posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002337{
2338 char *name;
2339 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002340 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002341 FILE *fp;
2342 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002343 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002344 return NULL;
2345 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002346 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002347 Py_END_ALLOW_THREADS
2348 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002349 return os2_error(err);
2350
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002351 f = PyFile_FromFile(fp, name, mode, fclose);
2352 if (f != NULL)
2353 PyFile_SetBufSize(f, bufsize);
2354 return f;
2355}
2356
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002357#elif defined(MS_WIN32)
2358
2359/*
2360 * Portable 'popen' replacement for Win32.
2361 *
2362 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2363 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002364 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002365 */
2366
2367#include <malloc.h>
2368#include <io.h>
2369#include <fcntl.h>
2370
2371/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2372#define POPEN_1 1
2373#define POPEN_2 2
2374#define POPEN_3 3
2375#define POPEN_4 4
2376
2377static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002378static int _PyPclose(FILE *file);
2379
2380/*
2381 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002382 * for use when retrieving the process exit code. See _PyPclose() below
2383 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002384 */
2385static PyObject *_PyPopenProcs = NULL;
2386
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002387
2388/* popen that works from a GUI.
2389 *
2390 * The result of this function is a pipe (file) connected to the
2391 * processes stdin or stdout, depending on the requested mode.
2392 */
2393
2394static PyObject *
2395posix_popen(PyObject *self, PyObject *args)
2396{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002397 PyObject *f, *s;
2398 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00002399
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002400 char *cmdstring;
2401 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002402 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002403 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002404 return NULL;
2405
2406 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00002407
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002408 if (*mode == 'r')
2409 tm = _O_RDONLY;
2410 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002411 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002412 return NULL;
2413 } else
2414 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00002415
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002416 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002417 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002418 return NULL;
2419 }
2420
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002421 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002422 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002423 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002424 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002425 else
2426 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2427
2428 return f;
2429}
2430
2431/* Variation on win32pipe.popen
2432 *
2433 * The result of this function is a pipe (file) connected to the
2434 * process's stdin, and a pipe connected to the process's stdout.
2435 */
2436
2437static PyObject *
2438win32_popen2(PyObject *self, PyObject *args)
2439{
2440 PyObject *f;
2441 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00002442
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002443 char *cmdstring;
2444 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002445 int bufsize = -1;
2446 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002447 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002448
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002449 if (*mode == 't')
2450 tm = _O_TEXT;
2451 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002452 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002453 return NULL;
2454 } else
2455 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00002456
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002457 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002458 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002459 return NULL;
2460 }
2461
2462 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00002463
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002464 return f;
2465}
2466
2467/*
2468 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002469 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002470 * The result of this function is 3 pipes - the process's stdin,
2471 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002472 */
2473
2474static PyObject *
2475win32_popen3(PyObject *self, PyObject *args)
2476{
2477 PyObject *f;
2478 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00002479
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002480 char *cmdstring;
2481 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002482 int bufsize = -1;
2483 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002484 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002485
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002486 if (*mode == 't')
2487 tm = _O_TEXT;
2488 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002489 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002490 return NULL;
2491 } else
2492 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00002493
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002494 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002495 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002496 return NULL;
2497 }
2498
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002499 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00002500
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002501 return f;
2502}
2503
2504/*
2505 * Variation on win32pipe.popen
2506 *
Tim Peters5aa91602002-01-30 05:46:57 +00002507 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002508 * and stdout+stderr combined as a single pipe.
2509 */
2510
2511static PyObject *
2512win32_popen4(PyObject *self, PyObject *args)
2513{
2514 PyObject *f;
2515 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00002516
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002517 char *cmdstring;
2518 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002519 int bufsize = -1;
2520 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002521 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002522
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002523 if (*mode == 't')
2524 tm = _O_TEXT;
2525 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002526 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002527 return NULL;
2528 } else
2529 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002530
2531 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002532 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002533 return NULL;
2534 }
2535
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002536 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002537
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002538 return f;
2539}
2540
Mark Hammond08501372001-01-31 07:30:29 +00002541static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002542_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002543 HANDLE hStdin,
2544 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002545 HANDLE hStderr,
2546 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002547{
2548 PROCESS_INFORMATION piProcInfo;
2549 STARTUPINFO siStartInfo;
2550 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002551 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002552 int i;
2553 int x;
2554
2555 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002556 char *comshell;
2557
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002558 s1 = (char *)_alloca(i);
2559 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2560 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002561
2562 /* Explicitly check if we are using COMMAND.COM. If we are
2563 * then use the w9xpopen hack.
2564 */
2565 comshell = s1 + x;
2566 while (comshell >= s1 && *comshell != '\\')
2567 --comshell;
2568 ++comshell;
2569
2570 if (GetVersion() < 0x80000000 &&
2571 _stricmp(comshell, "command.com") != 0) {
2572 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002573 x = i + strlen(s3) + strlen(cmdstring) + 1;
2574 s2 = (char *)_alloca(x);
2575 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002576 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002577 }
2578 else {
2579 /*
Tim Peters402d5982001-08-27 06:37:48 +00002580 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2581 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002582 */
Mark Hammond08501372001-01-31 07:30:29 +00002583 char modulepath[_MAX_PATH];
2584 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002585 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2586 for (i = x = 0; modulepath[i]; i++)
2587 if (modulepath[i] == '\\')
2588 x = i+1;
2589 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002590 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00002591 strncat(modulepath,
2592 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00002593 (sizeof(modulepath)/sizeof(modulepath[0]))
2594 -strlen(modulepath));
2595 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002596 /* Eeek - file-not-found - possibly an embedding
2597 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00002598 */
Tim Peters5aa91602002-01-30 05:46:57 +00002599 strncpy(modulepath,
2600 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00002601 sizeof(modulepath)/sizeof(modulepath[0]));
2602 if (modulepath[strlen(modulepath)-1] != '\\')
2603 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00002604 strncat(modulepath,
2605 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00002606 (sizeof(modulepath)/sizeof(modulepath[0]))
2607 -strlen(modulepath));
2608 /* No where else to look - raise an easily identifiable
2609 error, rather than leaving Windows to report
2610 "file not found" - as the user is probably blissfully
2611 unaware this shim EXE is used, and it will confuse them.
2612 (well, it confused me for a while ;-)
2613 */
2614 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002615 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00002616 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002617 "for popen to work with your shell "
2618 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002619 szConsoleSpawn);
2620 return FALSE;
2621 }
2622 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002623 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00002624 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002625 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002626
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002627 s2 = (char *)_alloca(x);
2628 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002629 PyOS_snprintf(
2630 s2, x,
Mark Hammond08501372001-01-31 07:30:29 +00002631 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002632 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002633 s1,
2634 s3,
2635 cmdstring);
2636 }
2637 }
2638
2639 /* Could be an else here to try cmd.exe / command.com in the path
2640 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002641 else {
Tim Peters402d5982001-08-27 06:37:48 +00002642 PyErr_SetString(PyExc_RuntimeError,
2643 "Cannot locate a COMSPEC environment variable to "
2644 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002645 return FALSE;
2646 }
Tim Peters5aa91602002-01-30 05:46:57 +00002647
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002648 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2649 siStartInfo.cb = sizeof(STARTUPINFO);
2650 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2651 siStartInfo.hStdInput = hStdin;
2652 siStartInfo.hStdOutput = hStdout;
2653 siStartInfo.hStdError = hStderr;
2654 siStartInfo.wShowWindow = SW_HIDE;
2655
2656 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002657 s2,
2658 NULL,
2659 NULL,
2660 TRUE,
2661 CREATE_NEW_CONSOLE,
2662 NULL,
2663 NULL,
2664 &siStartInfo,
2665 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002666 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002667 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002668
Mark Hammondb37a3732000-08-14 04:47:33 +00002669 /* Return process handle */
2670 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002671 return TRUE;
2672 }
Tim Peters402d5982001-08-27 06:37:48 +00002673 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002674 return FALSE;
2675}
2676
2677/* The following code is based off of KB: Q190351 */
2678
2679static PyObject *
2680_PyPopen(char *cmdstring, int mode, int n)
2681{
2682 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2683 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002684 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00002685
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002686 SECURITY_ATTRIBUTES saAttr;
2687 BOOL fSuccess;
2688 int fd1, fd2, fd3;
2689 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002690 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002691 PyObject *f;
2692
2693 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2694 saAttr.bInheritHandle = TRUE;
2695 saAttr.lpSecurityDescriptor = NULL;
2696
2697 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2698 return win32_error("CreatePipe", NULL);
2699
2700 /* Create new output read handle and the input write handle. Set
2701 * the inheritance properties to FALSE. Otherwise, the child inherits
2702 * the these handles; resulting in non-closeable handles to the pipes
2703 * being created. */
2704 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002705 GetCurrentProcess(), &hChildStdinWrDup, 0,
2706 FALSE,
2707 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002708 if (!fSuccess)
2709 return win32_error("DuplicateHandle", NULL);
2710
2711 /* Close the inheritable version of ChildStdin
2712 that we're using. */
2713 CloseHandle(hChildStdinWr);
2714
2715 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2716 return win32_error("CreatePipe", NULL);
2717
2718 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002719 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2720 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002721 if (!fSuccess)
2722 return win32_error("DuplicateHandle", NULL);
2723
2724 /* Close the inheritable version of ChildStdout
2725 that we're using. */
2726 CloseHandle(hChildStdoutRd);
2727
2728 if (n != POPEN_4) {
2729 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2730 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002731 fSuccess = DuplicateHandle(GetCurrentProcess(),
2732 hChildStderrRd,
2733 GetCurrentProcess(),
2734 &hChildStderrRdDup, 0,
2735 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002736 if (!fSuccess)
2737 return win32_error("DuplicateHandle", NULL);
2738 /* Close the inheritable version of ChildStdErr that we're using. */
2739 CloseHandle(hChildStderrRd);
2740 }
Tim Peters5aa91602002-01-30 05:46:57 +00002741
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002742 switch (n) {
2743 case POPEN_1:
2744 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2745 case _O_WRONLY | _O_TEXT:
2746 /* Case for writing to child Stdin in text mode. */
2747 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2748 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002749 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002750 PyFile_SetBufSize(f, 0);
2751 /* We don't care about these pipes anymore, so close them. */
2752 CloseHandle(hChildStdoutRdDup);
2753 CloseHandle(hChildStderrRdDup);
2754 break;
2755
2756 case _O_RDONLY | _O_TEXT:
2757 /* Case for reading from child Stdout in text mode. */
2758 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2759 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002760 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002761 PyFile_SetBufSize(f, 0);
2762 /* We don't care about these pipes anymore, so close them. */
2763 CloseHandle(hChildStdinWrDup);
2764 CloseHandle(hChildStderrRdDup);
2765 break;
2766
2767 case _O_RDONLY | _O_BINARY:
2768 /* Case for readinig from child Stdout in binary mode. */
2769 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2770 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002771 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002772 PyFile_SetBufSize(f, 0);
2773 /* We don't care about these pipes anymore, so close them. */
2774 CloseHandle(hChildStdinWrDup);
2775 CloseHandle(hChildStderrRdDup);
2776 break;
2777
2778 case _O_WRONLY | _O_BINARY:
2779 /* Case for writing to child Stdin in binary mode. */
2780 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2781 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002782 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002783 PyFile_SetBufSize(f, 0);
2784 /* We don't care about these pipes anymore, so close them. */
2785 CloseHandle(hChildStdoutRdDup);
2786 CloseHandle(hChildStderrRdDup);
2787 break;
2788 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002789 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002790 break;
Tim Peters5aa91602002-01-30 05:46:57 +00002791
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002792 case POPEN_2:
2793 case POPEN_4:
2794 {
2795 char *m1, *m2;
2796 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00002797
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002798 if (mode && _O_TEXT) {
2799 m1 = "r";
2800 m2 = "w";
2801 } else {
2802 m1 = "rb";
2803 m2 = "wb";
2804 }
2805
2806 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2807 f1 = _fdopen(fd1, m2);
2808 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2809 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002810 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002811 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002812 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002813 PyFile_SetBufSize(p2, 0);
2814
2815 if (n != 4)
2816 CloseHandle(hChildStderrRdDup);
2817
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002818 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002819 Py_XDECREF(p1);
2820 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002821 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002822 break;
2823 }
Tim Peters5aa91602002-01-30 05:46:57 +00002824
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002825 case POPEN_3:
2826 {
2827 char *m1, *m2;
2828 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00002829
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002830 if (mode && _O_TEXT) {
2831 m1 = "r";
2832 m2 = "w";
2833 } else {
2834 m1 = "rb";
2835 m2 = "wb";
2836 }
2837
2838 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2839 f1 = _fdopen(fd1, m2);
2840 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2841 f2 = _fdopen(fd2, m1);
2842 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2843 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002844 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002845 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2846 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002847 PyFile_SetBufSize(p1, 0);
2848 PyFile_SetBufSize(p2, 0);
2849 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002850 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002851 Py_XDECREF(p1);
2852 Py_XDECREF(p2);
2853 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002854 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002855 break;
2856 }
2857 }
2858
2859 if (n == POPEN_4) {
2860 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002861 hChildStdinRd,
2862 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002863 hChildStdoutWr,
2864 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002865 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002866 }
2867 else {
2868 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002869 hChildStdinRd,
2870 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002871 hChildStderrWr,
2872 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002873 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002874 }
2875
Mark Hammondb37a3732000-08-14 04:47:33 +00002876 /*
2877 * Insert the files we've created into the process dictionary
2878 * all referencing the list with the process handle and the
2879 * initial number of files (see description below in _PyPclose).
2880 * Since if _PyPclose later tried to wait on a process when all
2881 * handles weren't closed, it could create a deadlock with the
2882 * child, we spend some energy here to try to ensure that we
2883 * either insert all file handles into the dictionary or none
2884 * at all. It's a little clumsy with the various popen modes
2885 * and variable number of files involved.
2886 */
2887 if (!_PyPopenProcs) {
2888 _PyPopenProcs = PyDict_New();
2889 }
2890
2891 if (_PyPopenProcs) {
2892 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2893 int ins_rc[3];
2894
2895 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2896 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2897
2898 procObj = PyList_New(2);
2899 hProcessObj = PyLong_FromVoidPtr(hProcess);
2900 intObj = PyInt_FromLong(file_count);
2901
2902 if (procObj && hProcessObj && intObj) {
2903 PyList_SetItem(procObj,0,hProcessObj);
2904 PyList_SetItem(procObj,1,intObj);
2905
2906 fileObj[0] = PyLong_FromVoidPtr(f1);
2907 if (fileObj[0]) {
2908 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2909 fileObj[0],
2910 procObj);
2911 }
2912 if (file_count >= 2) {
2913 fileObj[1] = PyLong_FromVoidPtr(f2);
2914 if (fileObj[1]) {
2915 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2916 fileObj[1],
2917 procObj);
2918 }
2919 }
2920 if (file_count >= 3) {
2921 fileObj[2] = PyLong_FromVoidPtr(f3);
2922 if (fileObj[2]) {
2923 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2924 fileObj[2],
2925 procObj);
2926 }
2927 }
2928
2929 if (ins_rc[0] < 0 || !fileObj[0] ||
2930 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2931 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2932 /* Something failed - remove any dictionary
2933 * entries that did make it.
2934 */
2935 if (!ins_rc[0] && fileObj[0]) {
2936 PyDict_DelItem(_PyPopenProcs,
2937 fileObj[0]);
2938 }
2939 if (!ins_rc[1] && fileObj[1]) {
2940 PyDict_DelItem(_PyPopenProcs,
2941 fileObj[1]);
2942 }
2943 if (!ins_rc[2] && fileObj[2]) {
2944 PyDict_DelItem(_PyPopenProcs,
2945 fileObj[2]);
2946 }
2947 }
2948 }
Tim Peters5aa91602002-01-30 05:46:57 +00002949
Mark Hammondb37a3732000-08-14 04:47:33 +00002950 /*
2951 * Clean up our localized references for the dictionary keys
2952 * and value since PyDict_SetItem will Py_INCREF any copies
2953 * that got placed in the dictionary.
2954 */
2955 Py_XDECREF(procObj);
2956 Py_XDECREF(fileObj[0]);
2957 Py_XDECREF(fileObj[1]);
2958 Py_XDECREF(fileObj[2]);
2959 }
2960
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002961 /* Child is launched. Close the parents copy of those pipe
2962 * handles that only the child should have open. You need to
2963 * make sure that no handles to the write end of the output pipe
2964 * are maintained in this process or else the pipe will not close
2965 * when the child process exits and the ReadFile will hang. */
2966
2967 if (!CloseHandle(hChildStdinRd))
2968 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00002969
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002970 if (!CloseHandle(hChildStdoutWr))
2971 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00002972
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002973 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2974 return win32_error("CloseHandle", NULL);
2975
2976 return f;
2977}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002978
2979/*
2980 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2981 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002982 *
2983 * This function uses the _PyPopenProcs dictionary in order to map the
2984 * input file pointer to information about the process that was
2985 * originally created by the popen* call that created the file pointer.
2986 * The dictionary uses the file pointer as a key (with one entry
2987 * inserted for each file returned by the original popen* call) and a
2988 * single list object as the value for all files from a single call.
2989 * The list object contains the Win32 process handle at [0], and a file
2990 * count at [1], which is initialized to the total number of file
2991 * handles using that list.
2992 *
2993 * This function closes whichever handle it is passed, and decrements
2994 * the file count in the dictionary for the process handle pointed to
2995 * by this file. On the last close (when the file count reaches zero),
2996 * this function will wait for the child process and then return its
2997 * exit code as the result of the close() operation. This permits the
2998 * files to be closed in any order - it is always the close() of the
2999 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003000 */
Tim Peters736aa322000-09-01 06:51:24 +00003001
3002 /* RED_FLAG 31-Aug-2000 Tim
3003 * This is always called (today!) between a pair of
3004 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3005 * macros. So the thread running this has no valid thread state, as
3006 * far as Python is concerned. However, this calls some Python API
3007 * functions that cannot be called safely without a valid thread
3008 * state, in particular PyDict_GetItem.
3009 * As a temporary hack (although it may last for years ...), we
3010 * *rely* on not having a valid thread state in this function, in
3011 * order to create our own "from scratch".
3012 * This will deadlock if _PyPclose is ever called by a thread
3013 * holding the global lock.
3014 */
3015
Fredrik Lundh56055a42000-07-23 19:47:12 +00003016static int _PyPclose(FILE *file)
3017{
Fredrik Lundh20318932000-07-26 17:29:12 +00003018 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003019 DWORD exit_code;
3020 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003021 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3022 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003023#ifdef WITH_THREAD
3024 PyInterpreterState* pInterpreterState;
3025 PyThreadState* pThreadState;
3026#endif
3027
Fredrik Lundh20318932000-07-26 17:29:12 +00003028 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003029 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003030 */
3031 result = fclose(file);
3032
Tim Peters736aa322000-09-01 06:51:24 +00003033#ifdef WITH_THREAD
3034 /* Bootstrap a valid thread state into existence. */
3035 pInterpreterState = PyInterpreterState_New();
3036 if (!pInterpreterState) {
3037 /* Well, we're hosed now! We don't have a thread
3038 * state, so can't call a nice error routine, or raise
3039 * an exception. Just die.
3040 */
3041 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003042 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003043 return -1; /* unreachable */
3044 }
3045 pThreadState = PyThreadState_New(pInterpreterState);
3046 if (!pThreadState) {
3047 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003048 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003049 return -1; /* unreachable */
3050 }
3051 /* Grab the global lock. Note that this will deadlock if the
3052 * current thread already has the lock! (see RED_FLAG comments
3053 * before this function)
3054 */
3055 PyEval_RestoreThread(pThreadState);
3056#endif
3057
Fredrik Lundh56055a42000-07-23 19:47:12 +00003058 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003059 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3060 (procObj = PyDict_GetItem(_PyPopenProcs,
3061 fileObj)) != NULL &&
3062 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3063 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3064
3065 hProcess = PyLong_AsVoidPtr(hProcessObj);
3066 file_count = PyInt_AsLong(intObj);
3067
3068 if (file_count > 1) {
3069 /* Still other files referencing process */
3070 file_count--;
3071 PyList_SetItem(procObj,1,
3072 PyInt_FromLong(file_count));
3073 } else {
3074 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003075 if (result != EOF &&
3076 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3077 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003078 /* Possible truncation here in 16-bit environments, but
3079 * real exit codes are just the lower byte in any event.
3080 */
3081 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003082 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003083 /* Indicate failure - this will cause the file object
3084 * to raise an I/O error and translate the last Win32
3085 * error code from errno. We do have a problem with
3086 * last errors that overlap the normal errno table,
3087 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003088 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003089 if (result != EOF) {
3090 /* If the error wasn't from the fclose(), then
3091 * set errno for the file object error handling.
3092 */
3093 errno = GetLastError();
3094 }
3095 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003096 }
3097
3098 /* Free up the native handle at this point */
3099 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003100 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003101
Mark Hammondb37a3732000-08-14 04:47:33 +00003102 /* Remove this file pointer from dictionary */
3103 PyDict_DelItem(_PyPopenProcs, fileObj);
3104
3105 if (PyDict_Size(_PyPopenProcs) == 0) {
3106 Py_DECREF(_PyPopenProcs);
3107 _PyPopenProcs = NULL;
3108 }
3109
3110 } /* if object retrieval ok */
3111
3112 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003113 } /* if _PyPopenProcs */
3114
Tim Peters736aa322000-09-01 06:51:24 +00003115#ifdef WITH_THREAD
3116 /* Tear down the thread & interpreter states.
3117 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003118 * call the thread clear & delete functions, and indeed insist on
3119 * doing that themselves. The lock must be held during the clear, but
3120 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003121 */
3122 PyInterpreterState_Clear(pInterpreterState);
3123 PyEval_ReleaseThread(pThreadState);
3124 PyInterpreterState_Delete(pInterpreterState);
3125#endif
3126
Fredrik Lundh56055a42000-07-23 19:47:12 +00003127 return result;
3128}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003129
3130#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003131static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003132posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003133{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003134 char *name;
3135 char *mode = "r";
3136 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003137 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003138 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003139 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003140 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003141 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003142 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003143 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003144 if (fp == NULL)
3145 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003146 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003147 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003148 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003149 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003150}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003151#endif
3152
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003153#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Guido van Rossumb6775db1994-08-01 11:34:53 +00003156#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003157static char posix_setuid__doc__[] =
3158"setuid(uid) -> None\n\
3159Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003161posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003162{
3163 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003164 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003165 return NULL;
3166 if (setuid(uid) < 0)
3167 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003168 Py_INCREF(Py_None);
3169 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003170}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003171#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003172
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003173
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003174#ifdef HAVE_SETEUID
3175static char posix_seteuid__doc__[] =
3176"seteuid(uid) -> None\n\
3177Set the current process's effective user id.";
3178static PyObject *
3179posix_seteuid (PyObject *self, PyObject *args)
3180{
3181 int euid;
3182 if (!PyArg_ParseTuple(args, "i", &euid)) {
3183 return NULL;
3184 } else if (seteuid(euid) < 0) {
3185 return posix_error();
3186 } else {
3187 Py_INCREF(Py_None);
3188 return Py_None;
3189 }
3190}
3191#endif /* HAVE_SETEUID */
3192
3193#ifdef HAVE_SETEGID
3194static char posix_setegid__doc__[] =
3195"setegid(gid) -> None\n\
3196Set the current process's effective group id.";
3197static PyObject *
3198posix_setegid (PyObject *self, PyObject *args)
3199{
3200 int egid;
3201 if (!PyArg_ParseTuple(args, "i", &egid)) {
3202 return NULL;
3203 } else if (setegid(egid) < 0) {
3204 return posix_error();
3205 } else {
3206 Py_INCREF(Py_None);
3207 return Py_None;
3208 }
3209}
3210#endif /* HAVE_SETEGID */
3211
3212#ifdef HAVE_SETREUID
3213static char posix_setreuid__doc__[] =
3214"seteuid(ruid, euid) -> None\n\
3215Set the current process's real and effective user ids.";
3216static PyObject *
3217posix_setreuid (PyObject *self, PyObject *args)
3218{
3219 int ruid, euid;
3220 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3221 return NULL;
3222 } else if (setreuid(ruid, euid) < 0) {
3223 return posix_error();
3224 } else {
3225 Py_INCREF(Py_None);
3226 return Py_None;
3227 }
3228}
3229#endif /* HAVE_SETREUID */
3230
3231#ifdef HAVE_SETREGID
3232static char posix_setregid__doc__[] =
3233"setegid(rgid, egid) -> None\n\
3234Set the current process's real and effective group ids.";
3235static PyObject *
3236posix_setregid (PyObject *self, PyObject *args)
3237{
3238 int rgid, egid;
3239 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3240 return NULL;
3241 } else if (setregid(rgid, egid) < 0) {
3242 return posix_error();
3243 } else {
3244 Py_INCREF(Py_None);
3245 return Py_None;
3246 }
3247}
3248#endif /* HAVE_SETREGID */
3249
Guido van Rossumb6775db1994-08-01 11:34:53 +00003250#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003251static char posix_setgid__doc__[] =
3252"setgid(gid) -> None\n\
3253Set the current process's group id.";
3254
Barry Warsaw53699e91996-12-10 23:23:01 +00003255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003256posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003257{
3258 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003259 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003260 return NULL;
3261 if (setgid(gid) < 0)
3262 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003263 Py_INCREF(Py_None);
3264 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003265}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003266#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003267
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003268#ifdef HAVE_SETGROUPS
3269static char posix_setgroups__doc__[] =
3270"setgroups(list) -> None\n\
3271Set the groups of the current process to list.";
3272
3273static PyObject *
3274posix_setgroups(PyObject *self, PyObject *args)
3275{
3276 PyObject *groups;
3277 int i, len;
3278 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003279
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003280 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3281 return NULL;
3282 if (!PySequence_Check(groups)) {
3283 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3284 return NULL;
3285 }
3286 len = PySequence_Size(groups);
3287 if (len > MAX_GROUPS) {
3288 PyErr_SetString(PyExc_ValueError, "too many groups");
3289 return NULL;
3290 }
3291 for(i = 0; i < len; i++) {
3292 PyObject *elem;
3293 elem = PySequence_GetItem(groups, i);
3294 if (!elem)
3295 return NULL;
3296 if (!PyInt_Check(elem)) {
3297 PyErr_SetString(PyExc_TypeError,
3298 "groups must be integers");
3299 Py_DECREF(elem);
3300 return NULL;
3301 }
3302 /* XXX: check that value fits into gid_t. */
3303 grouplist[i] = PyInt_AsLong(elem);
3304 Py_DECREF(elem);
3305 }
3306
3307 if (setgroups(len, grouplist) < 0)
3308 return posix_error();
3309 Py_INCREF(Py_None);
3310 return Py_None;
3311}
3312#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003313
Guido van Rossumb6775db1994-08-01 11:34:53 +00003314#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003315static char posix_waitpid__doc__[] =
3316"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003317Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003318
Barry Warsaw53699e91996-12-10 23:23:01 +00003319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003320posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003321{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003322 int pid, options;
3323#ifdef UNION_WAIT
3324 union wait status;
3325#define status_i (status.w_status)
3326#else
3327 int status;
3328#define status_i status
3329#endif
3330 status_i = 0;
3331
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003332 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003333 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003334 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003335 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00003336 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003337 if (pid == -1)
3338 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003339 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003340 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003341}
3342
Tim Petersab034fa2002-02-01 11:27:43 +00003343#elif defined(HAVE_CWAIT)
3344
3345/* MS C has a variant of waitpid() that's usable for most purposes. */
3346static char posix_waitpid__doc__[] =
3347"waitpid(pid, options) -> (pid, status << 8)\n"
3348"Wait for completion of a given process. options is ignored on Windows.";
3349
3350static PyObject *
3351posix_waitpid(PyObject *self, PyObject *args)
3352{
3353 int pid, options;
3354 int status;
3355
3356 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
3357 return NULL;
3358 Py_BEGIN_ALLOW_THREADS
3359 pid = _cwait(&status, pid, options);
3360 Py_END_ALLOW_THREADS
3361 if (pid == -1)
3362 return posix_error();
3363 else
3364 /* shift the status left a byte so this is more like the
3365 POSIX waitpid */
3366 return Py_BuildValue("ii", pid, status << 8);
3367}
3368#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003369
Guido van Rossumad0ee831995-03-01 10:34:45 +00003370#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003371static char posix_wait__doc__[] =
3372"wait() -> (pid, status)\n\
3373Wait for completion of a child process.";
3374
Barry Warsaw53699e91996-12-10 23:23:01 +00003375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003376posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003377{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003378 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003379#ifdef UNION_WAIT
3380 union wait status;
3381#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003382#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003383 int status;
3384#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003385#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003386 if (!PyArg_ParseTuple(args, ":wait"))
3387 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003388 status_i = 0;
3389 Py_BEGIN_ALLOW_THREADS
3390 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003391 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003392 if (pid == -1)
3393 return posix_error();
3394 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003395 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003396#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003397}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003398#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003400
3401static char posix_lstat__doc__[] =
3402"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3403Like stat(path), but do not follow symbolic links.";
3404
Barry Warsaw53699e91996-12-10 23:23:01 +00003405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003406posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003407{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003408#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003409 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003410#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003411 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003412#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003413}
3414
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003415
Guido van Rossumb6775db1994-08-01 11:34:53 +00003416#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003417static char posix_readlink__doc__[] =
3418"readlink(path) -> path\n\
3419Return a string representing the path to which the symbolic link points.";
3420
Barry Warsaw53699e91996-12-10 23:23:01 +00003421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003422posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003423{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003424 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003425 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003426 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003427 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003428 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003429 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003430 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003431 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003432 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003433 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003434 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003435}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003436#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003437
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003438
Guido van Rossumb6775db1994-08-01 11:34:53 +00003439#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003440static char posix_symlink__doc__[] =
3441"symlink(src, dst) -> None\n\
3442Create a symbolic link.";
3443
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003445posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003446{
Mark Hammondef8b6542001-05-13 08:04:26 +00003447 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003448}
3449#endif /* HAVE_SYMLINK */
3450
3451
3452#ifdef HAVE_TIMES
3453#ifndef HZ
3454#define HZ 60 /* Universal constant :-) */
3455#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00003456
Guido van Rossumd48f2521997-12-05 22:19:34 +00003457#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3458static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003459system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003460{
3461 ULONG value = 0;
3462
3463 Py_BEGIN_ALLOW_THREADS
3464 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3465 Py_END_ALLOW_THREADS
3466
3467 return value;
3468}
3469
3470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003471posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003472{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003473 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003474 return NULL;
3475
3476 /* Currently Only Uptime is Provided -- Others Later */
3477 return Py_BuildValue("ddddd",
3478 (double)0 /* t.tms_utime / HZ */,
3479 (double)0 /* t.tms_stime / HZ */,
3480 (double)0 /* t.tms_cutime / HZ */,
3481 (double)0 /* t.tms_cstime / HZ */,
3482 (double)system_uptime() / 1000);
3483}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003484#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003486posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003487{
3488 struct tms t;
3489 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003490 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003491 return NULL;
3492 errno = 0;
3493 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003494 if (c == (clock_t) -1)
3495 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003496 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003497 (double)t.tms_utime / HZ,
3498 (double)t.tms_stime / HZ,
3499 (double)t.tms_cutime / HZ,
3500 (double)t.tms_cstime / HZ,
3501 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003502}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003503#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003504#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003505
3506
Guido van Rossum87755a21996-09-07 00:59:43 +00003507#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003508#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003510posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003511{
3512 FILETIME create, exit, kernel, user;
3513 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003514 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003515 return NULL;
3516 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003517 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3518 /* The fields of a FILETIME structure are the hi and lo part
3519 of a 64-bit value expressed in 100 nanosecond units.
3520 1e7 is one second in such units; 1e-7 the inverse.
3521 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3522 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003523 return Py_BuildValue(
3524 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003525 (double)(kernel.dwHighDateTime*429.4967296 +
3526 kernel.dwLowDateTime*1e-7),
3527 (double)(user.dwHighDateTime*429.4967296 +
3528 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003529 (double)0,
3530 (double)0,
3531 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003532}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003533#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003534
3535#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003536static char posix_times__doc__[] =
3537"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3538Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003539#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003541
Guido van Rossumb6775db1994-08-01 11:34:53 +00003542#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003543static char posix_setsid__doc__[] =
3544"setsid() -> None\n\
3545Call the system call setsid().";
3546
Barry Warsaw53699e91996-12-10 23:23:01 +00003547static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003548posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003549{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003550 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003551 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003552 if (setsid() < 0)
3553 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003554 Py_INCREF(Py_None);
3555 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003556}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003557#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003558
Guido van Rossumb6775db1994-08-01 11:34:53 +00003559#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003560static char posix_setpgid__doc__[] =
3561"setpgid(pid, pgrp) -> None\n\
3562Call the system call setpgid().";
3563
Barry Warsaw53699e91996-12-10 23:23:01 +00003564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003565posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003566{
3567 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003568 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003569 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003570 if (setpgid(pid, pgrp) < 0)
3571 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003572 Py_INCREF(Py_None);
3573 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003574}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003575#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003576
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003577
Guido van Rossumb6775db1994-08-01 11:34:53 +00003578#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003579static char posix_tcgetpgrp__doc__[] =
3580"tcgetpgrp(fd) -> pgid\n\
3581Return the process group associated with the terminal given by a fd.";
3582
Barry Warsaw53699e91996-12-10 23:23:01 +00003583static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003584posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003585{
3586 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003587 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003588 return NULL;
3589 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003590 if (pgid < 0)
3591 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003592 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003593}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003594#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003595
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003596
Guido van Rossumb6775db1994-08-01 11:34:53 +00003597#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003598static char posix_tcsetpgrp__doc__[] =
3599"tcsetpgrp(fd, pgid) -> None\n\
3600Set the process group associated with the terminal given by a fd.";
3601
Barry Warsaw53699e91996-12-10 23:23:01 +00003602static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003603posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003604{
3605 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003606 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003607 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003608 if (tcsetpgrp(fd, pgid) < 0)
3609 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003610 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003611 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003612}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003613#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003614
Guido van Rossum687dd131993-05-17 08:34:16 +00003615/* Functions acting on file descriptors */
3616
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003617static char posix_open__doc__[] =
3618"open(filename, flag [, mode=0777]) -> fd\n\
3619Open a file (for low level IO).";
3620
Barry Warsaw53699e91996-12-10 23:23:01 +00003621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003622posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003623{
Mark Hammondef8b6542001-05-13 08:04:26 +00003624 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003625 int flag;
3626 int mode = 0777;
3627 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00003628 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00003629 Py_FileSystemDefaultEncoding, &file,
3630 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003631 return NULL;
3632
Barry Warsaw53699e91996-12-10 23:23:01 +00003633 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003634 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003635 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003636 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003637 return posix_error_with_allocated_filename(file);
3638 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003639 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003640}
3641
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003642
3643static char posix_close__doc__[] =
3644"close(fd) -> None\n\
3645Close a file descriptor (for low level IO).";
3646
Barry Warsaw53699e91996-12-10 23:23:01 +00003647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003648posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003649{
3650 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003651 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003652 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003653 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003654 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003655 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003656 if (res < 0)
3657 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003658 Py_INCREF(Py_None);
3659 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003660}
3661
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003662
3663static char posix_dup__doc__[] =
3664"dup(fd) -> fd2\n\
3665Return a duplicate of a file descriptor.";
3666
Barry Warsaw53699e91996-12-10 23:23:01 +00003667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003668posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003669{
3670 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003671 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003672 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003673 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003674 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003675 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003676 if (fd < 0)
3677 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003678 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003679}
3680
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003681
3682static char posix_dup2__doc__[] =
3683"dup2(fd, fd2) -> None\n\
3684Duplicate file descriptor.";
3685
Barry Warsaw53699e91996-12-10 23:23:01 +00003686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003687posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003688{
3689 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003690 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003691 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003692 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003693 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003694 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003695 if (res < 0)
3696 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003697 Py_INCREF(Py_None);
3698 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003699}
3700
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003701
3702static char posix_lseek__doc__[] =
3703"lseek(fd, pos, how) -> newpos\n\
3704Set the current position of a file descriptor.";
3705
Barry Warsaw53699e91996-12-10 23:23:01 +00003706static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003707posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003708{
3709 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003710#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003711 LONG_LONG pos, res;
3712#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003713 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003714#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003715 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003716 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003717 return NULL;
3718#ifdef SEEK_SET
3719 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3720 switch (how) {
3721 case 0: how = SEEK_SET; break;
3722 case 1: how = SEEK_CUR; break;
3723 case 2: how = SEEK_END; break;
3724 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003725#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003726
3727#if !defined(HAVE_LARGEFILE_SUPPORT)
3728 pos = PyInt_AsLong(posobj);
3729#else
3730 pos = PyLong_Check(posobj) ?
3731 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3732#endif
3733 if (PyErr_Occurred())
3734 return NULL;
3735
Barry Warsaw53699e91996-12-10 23:23:01 +00003736 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003737#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003738 res = _lseeki64(fd, pos, how);
3739#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003740 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003741#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003742 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003743 if (res < 0)
3744 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003745
3746#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003747 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003748#else
3749 return PyLong_FromLongLong(res);
3750#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003751}
3752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003753
3754static char posix_read__doc__[] =
3755"read(fd, buffersize) -> string\n\
3756Read a file descriptor.";
3757
Barry Warsaw53699e91996-12-10 23:23:01 +00003758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003759posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003760{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003761 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003762 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003763 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003764 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003765 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003766 if (buffer == NULL)
3767 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003768 Py_BEGIN_ALLOW_THREADS
3769 n = read(fd, PyString_AsString(buffer), size);
3770 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003771 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003772 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003773 return posix_error();
3774 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003775 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003776 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003777 return buffer;
3778}
3779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003780
3781static char posix_write__doc__[] =
3782"write(fd, string) -> byteswritten\n\
3783Write a string to a file descriptor.";
3784
Barry Warsaw53699e91996-12-10 23:23:01 +00003785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003786posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003787{
3788 int fd, size;
3789 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003790 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003791 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003792 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003793 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003794 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003795 if (size < 0)
3796 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003797 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003798}
3799
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003800
3801static char posix_fstat__doc__[]=
3802"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3803Like stat(), but for an open file descriptor.";
3804
Barry Warsaw53699e91996-12-10 23:23:01 +00003805static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003806posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003807{
3808 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003809 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003810 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003811 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003812 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003813 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003814 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003815 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003816 if (res != 0)
3817 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00003818
Fred Drake699f3522000-06-29 21:12:41 +00003819 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003820}
3821
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003822
3823static char posix_fdopen__doc__[] =
3824"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3825Return an open file object connected to a file descriptor.";
3826
Barry Warsaw53699e91996-12-10 23:23:01 +00003827static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003828posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003829{
Guido van Rossum687dd131993-05-17 08:34:16 +00003830 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003831 char *mode = "r";
3832 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003833 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003834 PyObject *f;
3835 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003836 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003837
Barry Warsaw53699e91996-12-10 23:23:01 +00003838 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003839 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003840 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003841 if (fp == NULL)
3842 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003843 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003844 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003845 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003846 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003847}
3848
Skip Montanaro1517d842000-07-19 14:34:14 +00003849static char posix_isatty__doc__[] =
3850"isatty(fd) -> Boolean\n\
3851Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003852connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003853
3854static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003855posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003856{
3857 int fd;
3858 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3859 return NULL;
3860 return Py_BuildValue("i", isatty(fd));
3861}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003862
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003863#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003864static char posix_pipe__doc__[] =
3865"pipe() -> (read_end, write_end)\n\
3866Create a pipe.";
3867
Barry Warsaw53699e91996-12-10 23:23:01 +00003868static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003869posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003870{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003871#if defined(PYOS_OS2)
3872 HFILE read, write;
3873 APIRET rc;
3874
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003875 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003876 return NULL;
3877
3878 Py_BEGIN_ALLOW_THREADS
3879 rc = DosCreatePipe( &read, &write, 4096);
3880 Py_END_ALLOW_THREADS
3881 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003882 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003883
3884 return Py_BuildValue("(ii)", read, write);
3885#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003886#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003887 int fds[2];
3888 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003889 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003890 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003891 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003892 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003893 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003894 if (res != 0)
3895 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003896 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003897#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003898 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003899 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003900 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003901 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003902 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003903 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003904 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003905 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003906 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003907 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003908 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3909 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003910 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003911#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003912#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003913}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003914#endif /* HAVE_PIPE */
3915
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003916
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003917#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003918static char posix_mkfifo__doc__[] =
3919"mkfifo(file, [, mode=0666]) -> None\n\
3920Create a FIFO (a POSIX named pipe).";
3921
Barry Warsaw53699e91996-12-10 23:23:01 +00003922static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003923posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003924{
3925 char *file;
3926 int mode = 0666;
3927 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003928 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003929 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003930 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003931 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003932 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003933 if (res < 0)
3934 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003935 Py_INCREF(Py_None);
3936 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003937}
3938#endif
3939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003940
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003941#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003942static char posix_ftruncate__doc__[] =
3943"ftruncate(fd, length) -> None\n\
3944Truncate a file to a specified length.";
3945
Barry Warsaw53699e91996-12-10 23:23:01 +00003946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003947posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003948{
3949 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003950 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003951 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003952 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003953
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003954 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003955 return NULL;
3956
3957#if !defined(HAVE_LARGEFILE_SUPPORT)
3958 length = PyInt_AsLong(lenobj);
3959#else
3960 length = PyLong_Check(lenobj) ?
3961 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3962#endif
3963 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003964 return NULL;
3965
Barry Warsaw53699e91996-12-10 23:23:01 +00003966 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003967 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003968 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003969 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003970 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003971 return NULL;
3972 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003973 Py_INCREF(Py_None);
3974 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003975}
3976#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003977
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003978#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003979static char posix_putenv__doc__[] =
3980"putenv(key, value) -> None\n\
3981Change or add an environment variable.";
3982
Fred Drake762e2061999-08-26 17:23:54 +00003983/* Save putenv() parameters as values here, so we can collect them when they
3984 * get re-set with another call for the same key. */
3985static PyObject *posix_putenv_garbage;
3986
Tim Peters5aa91602002-01-30 05:46:57 +00003987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003988posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003989{
3990 char *s1, *s2;
3991 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003992 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00003993 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003994
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003995 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003996 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003997
3998#if defined(PYOS_OS2)
3999 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4000 APIRET rc;
4001
4002 if (strlen(s2) == 0) /* If New Value is an Empty String */
4003 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4004
4005 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4006 if (rc != NO_ERROR)
4007 return os2_error(rc);
4008
4009 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4010 APIRET rc;
4011
4012 if (strlen(s2) == 0) /* If New Value is an Empty String */
4013 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4014
4015 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4016 if (rc != NO_ERROR)
4017 return os2_error(rc);
4018 } else {
4019#endif
4020
Fred Drake762e2061999-08-26 17:23:54 +00004021 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004022 len = strlen(s1) + strlen(s2) + 2;
4023 /* len includes space for a trailing \0; the size arg to
4024 PyString_FromStringAndSize does not count that */
4025 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004026 if (newstr == NULL)
4027 return PyErr_NoMemory();
4028 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004029 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004030 if (putenv(new)) {
4031 posix_error();
4032 return NULL;
4033 }
Fred Drake762e2061999-08-26 17:23:54 +00004034 /* Install the first arg and newstr in posix_putenv_garbage;
4035 * this will cause previous value to be collected. This has to
4036 * happen after the real putenv() call because the old value
4037 * was still accessible until then. */
4038 if (PyDict_SetItem(posix_putenv_garbage,
4039 PyTuple_GET_ITEM(args, 0), newstr)) {
4040 /* really not much we can do; just leak */
4041 PyErr_Clear();
4042 }
4043 else {
4044 Py_DECREF(newstr);
4045 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004046
4047#if defined(PYOS_OS2)
4048 }
4049#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004050 Py_INCREF(Py_None);
4051 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004052}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004053#endif /* putenv */
4054
Guido van Rossumc524d952001-10-19 01:31:59 +00004055#ifdef HAVE_UNSETENV
4056static char posix_unsetenv__doc__[] =
4057"unsetenv(key) -> None\n\
4058Delete an environment variable.";
4059
4060static PyObject *
4061posix_unsetenv(PyObject *self, PyObject *args)
4062{
4063 char *s1;
4064
4065 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4066 return NULL;
4067
4068 unsetenv(s1);
4069
4070 /* Remove the key from posix_putenv_garbage;
4071 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004072 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004073 * old value was still accessible until then.
4074 */
4075 if (PyDict_DelItem(posix_putenv_garbage,
4076 PyTuple_GET_ITEM(args, 0))) {
4077 /* really not much we can do; just leak */
4078 PyErr_Clear();
4079 }
4080
4081 Py_INCREF(Py_None);
4082 return Py_None;
4083}
4084#endif /* unsetenv */
4085
Guido van Rossumb6a47161997-09-15 22:54:34 +00004086#ifdef HAVE_STRERROR
4087static char posix_strerror__doc__[] =
4088"strerror(code) -> string\n\
4089Translate an error code to a message string.";
4090
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004092posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004093{
4094 int code;
4095 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004096 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004097 return NULL;
4098 message = strerror(code);
4099 if (message == NULL) {
4100 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004101 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004102 return NULL;
4103 }
4104 return PyString_FromString(message);
4105}
4106#endif /* strerror */
4107
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004108
Guido van Rossumc9641791998-08-04 15:26:23 +00004109#ifdef HAVE_SYS_WAIT_H
4110
4111#ifdef WIFSTOPPED
4112static char posix_WIFSTOPPED__doc__[] =
4113"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004114Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004115
4116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004117posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004118{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004119#ifdef UNION_WAIT
4120 union wait status;
4121#define status_i (status.w_status)
4122#else
4123 int status;
4124#define status_i status
4125#endif
4126 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004127
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004128 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004129 {
4130 return NULL;
4131 }
Tim Peters5aa91602002-01-30 05:46:57 +00004132
Guido van Rossumc9641791998-08-04 15:26:23 +00004133 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004134#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004135}
4136#endif /* WIFSTOPPED */
4137
4138#ifdef WIFSIGNALED
4139static char posix_WIFSIGNALED__doc__[] =
4140"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004141Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004142
4143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004144posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004145{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004146#ifdef UNION_WAIT
4147 union wait status;
4148#define status_i (status.w_status)
4149#else
4150 int status;
4151#define status_i status
4152#endif
4153 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004154
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004155 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004156 {
4157 return NULL;
4158 }
Tim Peters5aa91602002-01-30 05:46:57 +00004159
Guido van Rossumc9641791998-08-04 15:26:23 +00004160 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004161#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004162}
4163#endif /* WIFSIGNALED */
4164
4165#ifdef WIFEXITED
4166static char posix_WIFEXITED__doc__[] =
4167"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004168Return true if the process returning 'status' exited using the exit()\n\
4169system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004170
4171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004172posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004173{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004174#ifdef UNION_WAIT
4175 union wait status;
4176#define status_i (status.w_status)
4177#else
4178 int status;
4179#define status_i status
4180#endif
4181 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004182
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004183 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004184 {
4185 return NULL;
4186 }
Tim Peters5aa91602002-01-30 05:46:57 +00004187
Guido van Rossumc9641791998-08-04 15:26:23 +00004188 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004189#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004190}
4191#endif /* WIFEXITED */
4192
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004193#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004194static char posix_WEXITSTATUS__doc__[] =
4195"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004196Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004197
4198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004199posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004200{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004201#ifdef UNION_WAIT
4202 union wait status;
4203#define status_i (status.w_status)
4204#else
4205 int status;
4206#define status_i status
4207#endif
4208 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004209
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004210 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004211 {
4212 return NULL;
4213 }
Tim Peters5aa91602002-01-30 05:46:57 +00004214
Guido van Rossumc9641791998-08-04 15:26:23 +00004215 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004216#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004217}
4218#endif /* WEXITSTATUS */
4219
4220#ifdef WTERMSIG
4221static char posix_WTERMSIG__doc__[] =
4222"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004223Return the signal that terminated the process that provided the 'status'\n\
4224value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004225
4226static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004227posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004228{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004229#ifdef UNION_WAIT
4230 union wait status;
4231#define status_i (status.w_status)
4232#else
4233 int status;
4234#define status_i status
4235#endif
4236 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004237
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004238 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004239 {
4240 return NULL;
4241 }
Tim Peters5aa91602002-01-30 05:46:57 +00004242
Guido van Rossumc9641791998-08-04 15:26:23 +00004243 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004244#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004245}
4246#endif /* WTERMSIG */
4247
4248#ifdef WSTOPSIG
4249static char posix_WSTOPSIG__doc__[] =
4250"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004251Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004252
4253static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004254posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004255{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004256#ifdef UNION_WAIT
4257 union wait status;
4258#define status_i (status.w_status)
4259#else
4260 int status;
4261#define status_i status
4262#endif
4263 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004264
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004265 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004266 {
4267 return NULL;
4268 }
Tim Peters5aa91602002-01-30 05:46:57 +00004269
Guido van Rossumc9641791998-08-04 15:26:23 +00004270 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004271#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004272}
4273#endif /* WSTOPSIG */
4274
4275#endif /* HAVE_SYS_WAIT_H */
4276
4277
Guido van Rossum94f6f721999-01-06 18:42:14 +00004278#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004279#ifdef _SCO_DS
4280/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4281 needed definitions in sys/statvfs.h */
4282#define _SVID3
4283#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004284#include <sys/statvfs.h>
4285
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004286static PyObject*
4287_pystatvfs_fromstructstatvfs(struct statvfs st) {
4288 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4289 if (v == NULL)
4290 return NULL;
4291
4292#if !defined(HAVE_LARGEFILE_SUPPORT)
4293 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4294 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4295 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4296 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4297 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4298 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4299 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4300 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4301 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4302 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4303#else
4304 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4305 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00004306 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004307 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00004308 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004309 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4310 PyStructSequence_SET_ITEM(v, 4,
4311 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00004312 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004313 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00004314 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004315 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00004316 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004317 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4318 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4319 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4320#endif
4321
4322 return v;
4323}
4324
Guido van Rossum94f6f721999-01-06 18:42:14 +00004325static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004326"fstatvfs(fd) -> \n\
4327 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004328Perform an fstatvfs system call on the given fd.";
4329
4330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004331posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004332{
4333 int fd, res;
4334 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004335
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004336 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004337 return NULL;
4338 Py_BEGIN_ALLOW_THREADS
4339 res = fstatvfs(fd, &st);
4340 Py_END_ALLOW_THREADS
4341 if (res != 0)
4342 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004343
4344 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004345}
4346#endif /* HAVE_FSTATVFS */
4347
4348
4349#if defined(HAVE_STATVFS)
4350#include <sys/statvfs.h>
4351
4352static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004353"statvfs(path) -> \n\
4354 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004355Perform a statvfs system call on the given path.";
4356
4357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004358posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004359{
4360 char *path;
4361 int res;
4362 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004363 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004364 return NULL;
4365 Py_BEGIN_ALLOW_THREADS
4366 res = statvfs(path, &st);
4367 Py_END_ALLOW_THREADS
4368 if (res != 0)
4369 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004370
4371 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004372}
4373#endif /* HAVE_STATVFS */
4374
4375
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004376#ifdef HAVE_TEMPNAM
4377static char posix_tempnam__doc__[] = "\
4378tempnam([dir[, prefix]]) -> string\n\
4379Return a unique name for a temporary file.\n\
4380The directory and a short may be specified as strings; they may be omitted\n\
4381or None if not needed.";
4382
4383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004384posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004385{
4386 PyObject *result = NULL;
4387 char *dir = NULL;
4388 char *pfx = NULL;
4389 char *name;
4390
4391 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4392 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004393
4394 if (PyErr_Warn(PyExc_RuntimeWarning,
4395 "tempnam is a potential security risk to your program") < 0)
4396 return NULL;
4397
Fred Drake78b71c22001-07-17 20:37:36 +00004398#ifdef MS_WIN32
4399 name = _tempnam(dir, pfx);
4400#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004401 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004402#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004403 if (name == NULL)
4404 return PyErr_NoMemory();
4405 result = PyString_FromString(name);
4406 free(name);
4407 return result;
4408}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004409#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004410
4411
4412#ifdef HAVE_TMPFILE
4413static char posix_tmpfile__doc__[] = "\
4414tmpfile() -> file object\n\
4415Create a temporary file with no directory entries.";
4416
4417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004418posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004419{
4420 FILE *fp;
4421
4422 if (!PyArg_ParseTuple(args, ":tmpfile"))
4423 return NULL;
4424 fp = tmpfile();
4425 if (fp == NULL)
4426 return posix_error();
4427 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4428}
4429#endif
4430
4431
4432#ifdef HAVE_TMPNAM
4433static char posix_tmpnam__doc__[] = "\
4434tmpnam() -> string\n\
4435Return a unique name for a temporary file.";
4436
4437static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004438posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004439{
4440 char buffer[L_tmpnam];
4441 char *name;
4442
4443 if (!PyArg_ParseTuple(args, ":tmpnam"))
4444 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004445
4446 if (PyErr_Warn(PyExc_RuntimeWarning,
4447 "tmpnam is a potential security risk to your program") < 0)
4448 return NULL;
4449
Greg Wardb48bc172000-03-01 21:51:56 +00004450#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004451 name = tmpnam_r(buffer);
4452#else
4453 name = tmpnam(buffer);
4454#endif
4455 if (name == NULL) {
4456 PyErr_SetObject(PyExc_OSError,
4457 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004458#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004459 "unexpected NULL from tmpnam_r"
4460#else
4461 "unexpected NULL from tmpnam"
4462#endif
4463 ));
4464 return NULL;
4465 }
4466 return PyString_FromString(buffer);
4467}
4468#endif
4469
4470
Fred Drakec9680921999-12-13 16:37:25 +00004471/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4472 * It maps strings representing configuration variable names to
4473 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004474 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004475 * rarely-used constants. There are three separate tables that use
4476 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004477 *
4478 * This code is always included, even if none of the interfaces that
4479 * need it are included. The #if hackery needed to avoid it would be
4480 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004481 */
4482struct constdef {
4483 char *name;
4484 long value;
4485};
4486
Fred Drake12c6e2d1999-12-14 21:25:03 +00004487static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004488conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4489 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004490{
4491 if (PyInt_Check(arg)) {
4492 *valuep = PyInt_AS_LONG(arg);
4493 return 1;
4494 }
4495 if (PyString_Check(arg)) {
4496 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004497 size_t lo = 0;
4498 size_t mid;
4499 size_t hi = tablesize;
4500 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004501 char *confname = PyString_AS_STRING(arg);
4502 while (lo < hi) {
4503 mid = (lo + hi) / 2;
4504 cmp = strcmp(confname, table[mid].name);
4505 if (cmp < 0)
4506 hi = mid;
4507 else if (cmp > 0)
4508 lo = mid + 1;
4509 else {
4510 *valuep = table[mid].value;
4511 return 1;
4512 }
4513 }
4514 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4515 }
4516 else
4517 PyErr_SetString(PyExc_TypeError,
4518 "configuration names must be strings or integers");
4519 return 0;
4520}
4521
4522
4523#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4524static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004525#ifdef _PC_ABI_AIO_XFER_MAX
4526 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4527#endif
4528#ifdef _PC_ABI_ASYNC_IO
4529 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4530#endif
Fred Drakec9680921999-12-13 16:37:25 +00004531#ifdef _PC_ASYNC_IO
4532 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4533#endif
4534#ifdef _PC_CHOWN_RESTRICTED
4535 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4536#endif
4537#ifdef _PC_FILESIZEBITS
4538 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4539#endif
4540#ifdef _PC_LAST
4541 {"PC_LAST", _PC_LAST},
4542#endif
4543#ifdef _PC_LINK_MAX
4544 {"PC_LINK_MAX", _PC_LINK_MAX},
4545#endif
4546#ifdef _PC_MAX_CANON
4547 {"PC_MAX_CANON", _PC_MAX_CANON},
4548#endif
4549#ifdef _PC_MAX_INPUT
4550 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4551#endif
4552#ifdef _PC_NAME_MAX
4553 {"PC_NAME_MAX", _PC_NAME_MAX},
4554#endif
4555#ifdef _PC_NO_TRUNC
4556 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4557#endif
4558#ifdef _PC_PATH_MAX
4559 {"PC_PATH_MAX", _PC_PATH_MAX},
4560#endif
4561#ifdef _PC_PIPE_BUF
4562 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4563#endif
4564#ifdef _PC_PRIO_IO
4565 {"PC_PRIO_IO", _PC_PRIO_IO},
4566#endif
4567#ifdef _PC_SOCK_MAXBUF
4568 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4569#endif
4570#ifdef _PC_SYNC_IO
4571 {"PC_SYNC_IO", _PC_SYNC_IO},
4572#endif
4573#ifdef _PC_VDISABLE
4574 {"PC_VDISABLE", _PC_VDISABLE},
4575#endif
4576};
4577
Fred Drakec9680921999-12-13 16:37:25 +00004578static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004579conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004580{
4581 return conv_confname(arg, valuep, posix_constants_pathconf,
4582 sizeof(posix_constants_pathconf)
4583 / sizeof(struct constdef));
4584}
4585#endif
4586
4587#ifdef HAVE_FPATHCONF
4588static char posix_fpathconf__doc__[] = "\
4589fpathconf(fd, name) -> integer\n\
4590Return the configuration limit name for the file descriptor fd.\n\
4591If there is no limit, return -1.";
4592
4593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004594posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004595{
4596 PyObject *result = NULL;
4597 int name, fd;
4598
Fred Drake12c6e2d1999-12-14 21:25:03 +00004599 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4600 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004601 long limit;
4602
4603 errno = 0;
4604 limit = fpathconf(fd, name);
4605 if (limit == -1 && errno != 0)
4606 posix_error();
4607 else
4608 result = PyInt_FromLong(limit);
4609 }
4610 return result;
4611}
4612#endif
4613
4614
4615#ifdef HAVE_PATHCONF
4616static char posix_pathconf__doc__[] = "\
4617pathconf(path, name) -> integer\n\
4618Return the configuration limit name for the file or directory path.\n\
4619If there is no limit, return -1.";
4620
4621static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004622posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004623{
4624 PyObject *result = NULL;
4625 int name;
4626 char *path;
4627
4628 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4629 conv_path_confname, &name)) {
4630 long limit;
4631
4632 errno = 0;
4633 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004634 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004635 if (errno == EINVAL)
4636 /* could be a path or name problem */
4637 posix_error();
4638 else
4639 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004640 }
Fred Drakec9680921999-12-13 16:37:25 +00004641 else
4642 result = PyInt_FromLong(limit);
4643 }
4644 return result;
4645}
4646#endif
4647
4648#ifdef HAVE_CONFSTR
4649static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004650#ifdef _CS_ARCHITECTURE
4651 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4652#endif
4653#ifdef _CS_HOSTNAME
4654 {"CS_HOSTNAME", _CS_HOSTNAME},
4655#endif
4656#ifdef _CS_HW_PROVIDER
4657 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4658#endif
4659#ifdef _CS_HW_SERIAL
4660 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4661#endif
4662#ifdef _CS_INITTAB_NAME
4663 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4664#endif
Fred Drakec9680921999-12-13 16:37:25 +00004665#ifdef _CS_LFS64_CFLAGS
4666 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4667#endif
4668#ifdef _CS_LFS64_LDFLAGS
4669 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4670#endif
4671#ifdef _CS_LFS64_LIBS
4672 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4673#endif
4674#ifdef _CS_LFS64_LINTFLAGS
4675 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4676#endif
4677#ifdef _CS_LFS_CFLAGS
4678 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4679#endif
4680#ifdef _CS_LFS_LDFLAGS
4681 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4682#endif
4683#ifdef _CS_LFS_LIBS
4684 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4685#endif
4686#ifdef _CS_LFS_LINTFLAGS
4687 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4688#endif
Fred Draked86ed291999-12-15 15:34:33 +00004689#ifdef _CS_MACHINE
4690 {"CS_MACHINE", _CS_MACHINE},
4691#endif
Fred Drakec9680921999-12-13 16:37:25 +00004692#ifdef _CS_PATH
4693 {"CS_PATH", _CS_PATH},
4694#endif
Fred Draked86ed291999-12-15 15:34:33 +00004695#ifdef _CS_RELEASE
4696 {"CS_RELEASE", _CS_RELEASE},
4697#endif
4698#ifdef _CS_SRPC_DOMAIN
4699 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4700#endif
4701#ifdef _CS_SYSNAME
4702 {"CS_SYSNAME", _CS_SYSNAME},
4703#endif
4704#ifdef _CS_VERSION
4705 {"CS_VERSION", _CS_VERSION},
4706#endif
Fred Drakec9680921999-12-13 16:37:25 +00004707#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4708 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4709#endif
4710#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4711 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4712#endif
4713#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4714 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4715#endif
4716#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4717 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4718#endif
4719#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4720 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4721#endif
4722#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4723 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4724#endif
4725#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4726 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4727#endif
4728#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4729 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4730#endif
4731#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4732 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4733#endif
4734#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4735 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4736#endif
4737#ifdef _CS_XBS5_LP64_OFF64_LIBS
4738 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4739#endif
4740#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4741 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4742#endif
4743#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4744 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4745#endif
4746#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4747 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4748#endif
4749#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4750 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4751#endif
4752#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4753 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4754#endif
Fred Draked86ed291999-12-15 15:34:33 +00004755#ifdef _MIPS_CS_AVAIL_PROCESSORS
4756 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4757#endif
4758#ifdef _MIPS_CS_BASE
4759 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4760#endif
4761#ifdef _MIPS_CS_HOSTID
4762 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4763#endif
4764#ifdef _MIPS_CS_HW_NAME
4765 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4766#endif
4767#ifdef _MIPS_CS_NUM_PROCESSORS
4768 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4769#endif
4770#ifdef _MIPS_CS_OSREL_MAJ
4771 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4772#endif
4773#ifdef _MIPS_CS_OSREL_MIN
4774 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4775#endif
4776#ifdef _MIPS_CS_OSREL_PATCH
4777 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4778#endif
4779#ifdef _MIPS_CS_OS_NAME
4780 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4781#endif
4782#ifdef _MIPS_CS_OS_PROVIDER
4783 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4784#endif
4785#ifdef _MIPS_CS_PROCESSORS
4786 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4787#endif
4788#ifdef _MIPS_CS_SERIAL
4789 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4790#endif
4791#ifdef _MIPS_CS_VENDOR
4792 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4793#endif
Fred Drakec9680921999-12-13 16:37:25 +00004794};
4795
4796static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004797conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004798{
4799 return conv_confname(arg, valuep, posix_constants_confstr,
4800 sizeof(posix_constants_confstr)
4801 / sizeof(struct constdef));
4802}
4803
4804static char posix_confstr__doc__[] = "\
4805confstr(name) -> string\n\
4806Return a string-valued system configuration variable.";
4807
4808static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004809posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004810{
4811 PyObject *result = NULL;
4812 int name;
4813 char buffer[64];
4814
4815 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4816 int len = confstr(name, buffer, sizeof(buffer));
4817
Fred Drakec9680921999-12-13 16:37:25 +00004818 errno = 0;
4819 if (len == 0) {
4820 if (errno != 0)
4821 posix_error();
4822 else
4823 result = PyString_FromString("");
4824 }
4825 else {
4826 if (len >= sizeof(buffer)) {
4827 result = PyString_FromStringAndSize(NULL, len);
4828 if (result != NULL)
4829 confstr(name, PyString_AS_STRING(result), len+1);
4830 }
4831 else
4832 result = PyString_FromString(buffer);
4833 }
4834 }
4835 return result;
4836}
4837#endif
4838
4839
4840#ifdef HAVE_SYSCONF
4841static struct constdef posix_constants_sysconf[] = {
4842#ifdef _SC_2_CHAR_TERM
4843 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4844#endif
4845#ifdef _SC_2_C_BIND
4846 {"SC_2_C_BIND", _SC_2_C_BIND},
4847#endif
4848#ifdef _SC_2_C_DEV
4849 {"SC_2_C_DEV", _SC_2_C_DEV},
4850#endif
4851#ifdef _SC_2_C_VERSION
4852 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4853#endif
4854#ifdef _SC_2_FORT_DEV
4855 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4856#endif
4857#ifdef _SC_2_FORT_RUN
4858 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4859#endif
4860#ifdef _SC_2_LOCALEDEF
4861 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4862#endif
4863#ifdef _SC_2_SW_DEV
4864 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4865#endif
4866#ifdef _SC_2_UPE
4867 {"SC_2_UPE", _SC_2_UPE},
4868#endif
4869#ifdef _SC_2_VERSION
4870 {"SC_2_VERSION", _SC_2_VERSION},
4871#endif
Fred Draked86ed291999-12-15 15:34:33 +00004872#ifdef _SC_ABI_ASYNCHRONOUS_IO
4873 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4874#endif
4875#ifdef _SC_ACL
4876 {"SC_ACL", _SC_ACL},
4877#endif
Fred Drakec9680921999-12-13 16:37:25 +00004878#ifdef _SC_AIO_LISTIO_MAX
4879 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4880#endif
Fred Drakec9680921999-12-13 16:37:25 +00004881#ifdef _SC_AIO_MAX
4882 {"SC_AIO_MAX", _SC_AIO_MAX},
4883#endif
4884#ifdef _SC_AIO_PRIO_DELTA_MAX
4885 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4886#endif
4887#ifdef _SC_ARG_MAX
4888 {"SC_ARG_MAX", _SC_ARG_MAX},
4889#endif
4890#ifdef _SC_ASYNCHRONOUS_IO
4891 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4892#endif
4893#ifdef _SC_ATEXIT_MAX
4894 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4895#endif
Fred Draked86ed291999-12-15 15:34:33 +00004896#ifdef _SC_AUDIT
4897 {"SC_AUDIT", _SC_AUDIT},
4898#endif
Fred Drakec9680921999-12-13 16:37:25 +00004899#ifdef _SC_AVPHYS_PAGES
4900 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4901#endif
4902#ifdef _SC_BC_BASE_MAX
4903 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4904#endif
4905#ifdef _SC_BC_DIM_MAX
4906 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4907#endif
4908#ifdef _SC_BC_SCALE_MAX
4909 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4910#endif
4911#ifdef _SC_BC_STRING_MAX
4912 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4913#endif
Fred Draked86ed291999-12-15 15:34:33 +00004914#ifdef _SC_CAP
4915 {"SC_CAP", _SC_CAP},
4916#endif
Fred Drakec9680921999-12-13 16:37:25 +00004917#ifdef _SC_CHARCLASS_NAME_MAX
4918 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4919#endif
4920#ifdef _SC_CHAR_BIT
4921 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4922#endif
4923#ifdef _SC_CHAR_MAX
4924 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4925#endif
4926#ifdef _SC_CHAR_MIN
4927 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4928#endif
4929#ifdef _SC_CHILD_MAX
4930 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4931#endif
4932#ifdef _SC_CLK_TCK
4933 {"SC_CLK_TCK", _SC_CLK_TCK},
4934#endif
4935#ifdef _SC_COHER_BLKSZ
4936 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4937#endif
4938#ifdef _SC_COLL_WEIGHTS_MAX
4939 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4940#endif
4941#ifdef _SC_DCACHE_ASSOC
4942 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4943#endif
4944#ifdef _SC_DCACHE_BLKSZ
4945 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4946#endif
4947#ifdef _SC_DCACHE_LINESZ
4948 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4949#endif
4950#ifdef _SC_DCACHE_SZ
4951 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4952#endif
4953#ifdef _SC_DCACHE_TBLKSZ
4954 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4955#endif
4956#ifdef _SC_DELAYTIMER_MAX
4957 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4958#endif
4959#ifdef _SC_EQUIV_CLASS_MAX
4960 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4961#endif
4962#ifdef _SC_EXPR_NEST_MAX
4963 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4964#endif
4965#ifdef _SC_FSYNC
4966 {"SC_FSYNC", _SC_FSYNC},
4967#endif
4968#ifdef _SC_GETGR_R_SIZE_MAX
4969 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4970#endif
4971#ifdef _SC_GETPW_R_SIZE_MAX
4972 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4973#endif
4974#ifdef _SC_ICACHE_ASSOC
4975 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4976#endif
4977#ifdef _SC_ICACHE_BLKSZ
4978 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4979#endif
4980#ifdef _SC_ICACHE_LINESZ
4981 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4982#endif
4983#ifdef _SC_ICACHE_SZ
4984 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4985#endif
Fred Draked86ed291999-12-15 15:34:33 +00004986#ifdef _SC_INF
4987 {"SC_INF", _SC_INF},
4988#endif
Fred Drakec9680921999-12-13 16:37:25 +00004989#ifdef _SC_INT_MAX
4990 {"SC_INT_MAX", _SC_INT_MAX},
4991#endif
4992#ifdef _SC_INT_MIN
4993 {"SC_INT_MIN", _SC_INT_MIN},
4994#endif
4995#ifdef _SC_IOV_MAX
4996 {"SC_IOV_MAX", _SC_IOV_MAX},
4997#endif
Fred Draked86ed291999-12-15 15:34:33 +00004998#ifdef _SC_IP_SECOPTS
4999 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5000#endif
Fred Drakec9680921999-12-13 16:37:25 +00005001#ifdef _SC_JOB_CONTROL
5002 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5003#endif
Fred Draked86ed291999-12-15 15:34:33 +00005004#ifdef _SC_KERN_POINTERS
5005 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5006#endif
5007#ifdef _SC_KERN_SIM
5008 {"SC_KERN_SIM", _SC_KERN_SIM},
5009#endif
Fred Drakec9680921999-12-13 16:37:25 +00005010#ifdef _SC_LINE_MAX
5011 {"SC_LINE_MAX", _SC_LINE_MAX},
5012#endif
5013#ifdef _SC_LOGIN_NAME_MAX
5014 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5015#endif
5016#ifdef _SC_LOGNAME_MAX
5017 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5018#endif
5019#ifdef _SC_LONG_BIT
5020 {"SC_LONG_BIT", _SC_LONG_BIT},
5021#endif
Fred Draked86ed291999-12-15 15:34:33 +00005022#ifdef _SC_MAC
5023 {"SC_MAC", _SC_MAC},
5024#endif
Fred Drakec9680921999-12-13 16:37:25 +00005025#ifdef _SC_MAPPED_FILES
5026 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5027#endif
5028#ifdef _SC_MAXPID
5029 {"SC_MAXPID", _SC_MAXPID},
5030#endif
5031#ifdef _SC_MB_LEN_MAX
5032 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5033#endif
5034#ifdef _SC_MEMLOCK
5035 {"SC_MEMLOCK", _SC_MEMLOCK},
5036#endif
5037#ifdef _SC_MEMLOCK_RANGE
5038 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5039#endif
5040#ifdef _SC_MEMORY_PROTECTION
5041 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5042#endif
5043#ifdef _SC_MESSAGE_PASSING
5044 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5045#endif
Fred Draked86ed291999-12-15 15:34:33 +00005046#ifdef _SC_MMAP_FIXED_ALIGNMENT
5047 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5048#endif
Fred Drakec9680921999-12-13 16:37:25 +00005049#ifdef _SC_MQ_OPEN_MAX
5050 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5051#endif
5052#ifdef _SC_MQ_PRIO_MAX
5053 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5054#endif
Fred Draked86ed291999-12-15 15:34:33 +00005055#ifdef _SC_NACLS_MAX
5056 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5057#endif
Fred Drakec9680921999-12-13 16:37:25 +00005058#ifdef _SC_NGROUPS_MAX
5059 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5060#endif
5061#ifdef _SC_NL_ARGMAX
5062 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5063#endif
5064#ifdef _SC_NL_LANGMAX
5065 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5066#endif
5067#ifdef _SC_NL_MSGMAX
5068 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5069#endif
5070#ifdef _SC_NL_NMAX
5071 {"SC_NL_NMAX", _SC_NL_NMAX},
5072#endif
5073#ifdef _SC_NL_SETMAX
5074 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5075#endif
5076#ifdef _SC_NL_TEXTMAX
5077 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5078#endif
5079#ifdef _SC_NPROCESSORS_CONF
5080 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5081#endif
5082#ifdef _SC_NPROCESSORS_ONLN
5083 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5084#endif
Fred Draked86ed291999-12-15 15:34:33 +00005085#ifdef _SC_NPROC_CONF
5086 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5087#endif
5088#ifdef _SC_NPROC_ONLN
5089 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5090#endif
Fred Drakec9680921999-12-13 16:37:25 +00005091#ifdef _SC_NZERO
5092 {"SC_NZERO", _SC_NZERO},
5093#endif
5094#ifdef _SC_OPEN_MAX
5095 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5096#endif
5097#ifdef _SC_PAGESIZE
5098 {"SC_PAGESIZE", _SC_PAGESIZE},
5099#endif
5100#ifdef _SC_PAGE_SIZE
5101 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5102#endif
5103#ifdef _SC_PASS_MAX
5104 {"SC_PASS_MAX", _SC_PASS_MAX},
5105#endif
5106#ifdef _SC_PHYS_PAGES
5107 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5108#endif
5109#ifdef _SC_PII
5110 {"SC_PII", _SC_PII},
5111#endif
5112#ifdef _SC_PII_INTERNET
5113 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5114#endif
5115#ifdef _SC_PII_INTERNET_DGRAM
5116 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5117#endif
5118#ifdef _SC_PII_INTERNET_STREAM
5119 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5120#endif
5121#ifdef _SC_PII_OSI
5122 {"SC_PII_OSI", _SC_PII_OSI},
5123#endif
5124#ifdef _SC_PII_OSI_CLTS
5125 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5126#endif
5127#ifdef _SC_PII_OSI_COTS
5128 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5129#endif
5130#ifdef _SC_PII_OSI_M
5131 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5132#endif
5133#ifdef _SC_PII_SOCKET
5134 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5135#endif
5136#ifdef _SC_PII_XTI
5137 {"SC_PII_XTI", _SC_PII_XTI},
5138#endif
5139#ifdef _SC_POLL
5140 {"SC_POLL", _SC_POLL},
5141#endif
5142#ifdef _SC_PRIORITIZED_IO
5143 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5144#endif
5145#ifdef _SC_PRIORITY_SCHEDULING
5146 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5147#endif
5148#ifdef _SC_REALTIME_SIGNALS
5149 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5150#endif
5151#ifdef _SC_RE_DUP_MAX
5152 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5153#endif
5154#ifdef _SC_RTSIG_MAX
5155 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5156#endif
5157#ifdef _SC_SAVED_IDS
5158 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5159#endif
5160#ifdef _SC_SCHAR_MAX
5161 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5162#endif
5163#ifdef _SC_SCHAR_MIN
5164 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5165#endif
5166#ifdef _SC_SELECT
5167 {"SC_SELECT", _SC_SELECT},
5168#endif
5169#ifdef _SC_SEMAPHORES
5170 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5171#endif
5172#ifdef _SC_SEM_NSEMS_MAX
5173 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5174#endif
5175#ifdef _SC_SEM_VALUE_MAX
5176 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5177#endif
5178#ifdef _SC_SHARED_MEMORY_OBJECTS
5179 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5180#endif
5181#ifdef _SC_SHRT_MAX
5182 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5183#endif
5184#ifdef _SC_SHRT_MIN
5185 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5186#endif
5187#ifdef _SC_SIGQUEUE_MAX
5188 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5189#endif
5190#ifdef _SC_SIGRT_MAX
5191 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5192#endif
5193#ifdef _SC_SIGRT_MIN
5194 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5195#endif
Fred Draked86ed291999-12-15 15:34:33 +00005196#ifdef _SC_SOFTPOWER
5197 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5198#endif
Fred Drakec9680921999-12-13 16:37:25 +00005199#ifdef _SC_SPLIT_CACHE
5200 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5201#endif
5202#ifdef _SC_SSIZE_MAX
5203 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5204#endif
5205#ifdef _SC_STACK_PROT
5206 {"SC_STACK_PROT", _SC_STACK_PROT},
5207#endif
5208#ifdef _SC_STREAM_MAX
5209 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5210#endif
5211#ifdef _SC_SYNCHRONIZED_IO
5212 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5213#endif
5214#ifdef _SC_THREADS
5215 {"SC_THREADS", _SC_THREADS},
5216#endif
5217#ifdef _SC_THREAD_ATTR_STACKADDR
5218 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5219#endif
5220#ifdef _SC_THREAD_ATTR_STACKSIZE
5221 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5222#endif
5223#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5224 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5225#endif
5226#ifdef _SC_THREAD_KEYS_MAX
5227 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5228#endif
5229#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5230 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5231#endif
5232#ifdef _SC_THREAD_PRIO_INHERIT
5233 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5234#endif
5235#ifdef _SC_THREAD_PRIO_PROTECT
5236 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5237#endif
5238#ifdef _SC_THREAD_PROCESS_SHARED
5239 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5240#endif
5241#ifdef _SC_THREAD_SAFE_FUNCTIONS
5242 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5243#endif
5244#ifdef _SC_THREAD_STACK_MIN
5245 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5246#endif
5247#ifdef _SC_THREAD_THREADS_MAX
5248 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5249#endif
5250#ifdef _SC_TIMERS
5251 {"SC_TIMERS", _SC_TIMERS},
5252#endif
5253#ifdef _SC_TIMER_MAX
5254 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5255#endif
5256#ifdef _SC_TTY_NAME_MAX
5257 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5258#endif
5259#ifdef _SC_TZNAME_MAX
5260 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5261#endif
5262#ifdef _SC_T_IOV_MAX
5263 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5264#endif
5265#ifdef _SC_UCHAR_MAX
5266 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5267#endif
5268#ifdef _SC_UINT_MAX
5269 {"SC_UINT_MAX", _SC_UINT_MAX},
5270#endif
5271#ifdef _SC_UIO_MAXIOV
5272 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5273#endif
5274#ifdef _SC_ULONG_MAX
5275 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5276#endif
5277#ifdef _SC_USHRT_MAX
5278 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5279#endif
5280#ifdef _SC_VERSION
5281 {"SC_VERSION", _SC_VERSION},
5282#endif
5283#ifdef _SC_WORD_BIT
5284 {"SC_WORD_BIT", _SC_WORD_BIT},
5285#endif
5286#ifdef _SC_XBS5_ILP32_OFF32
5287 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5288#endif
5289#ifdef _SC_XBS5_ILP32_OFFBIG
5290 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5291#endif
5292#ifdef _SC_XBS5_LP64_OFF64
5293 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5294#endif
5295#ifdef _SC_XBS5_LPBIG_OFFBIG
5296 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5297#endif
5298#ifdef _SC_XOPEN_CRYPT
5299 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5300#endif
5301#ifdef _SC_XOPEN_ENH_I18N
5302 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5303#endif
5304#ifdef _SC_XOPEN_LEGACY
5305 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5306#endif
5307#ifdef _SC_XOPEN_REALTIME
5308 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5309#endif
5310#ifdef _SC_XOPEN_REALTIME_THREADS
5311 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5312#endif
5313#ifdef _SC_XOPEN_SHM
5314 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5315#endif
5316#ifdef _SC_XOPEN_UNIX
5317 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5318#endif
5319#ifdef _SC_XOPEN_VERSION
5320 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5321#endif
5322#ifdef _SC_XOPEN_XCU_VERSION
5323 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5324#endif
5325#ifdef _SC_XOPEN_XPG2
5326 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5327#endif
5328#ifdef _SC_XOPEN_XPG3
5329 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5330#endif
5331#ifdef _SC_XOPEN_XPG4
5332 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5333#endif
5334};
5335
5336static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005337conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005338{
5339 return conv_confname(arg, valuep, posix_constants_sysconf,
5340 sizeof(posix_constants_sysconf)
5341 / sizeof(struct constdef));
5342}
5343
5344static char posix_sysconf__doc__[] = "\
5345sysconf(name) -> integer\n\
5346Return an integer-valued system configuration variable.";
5347
5348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005349posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005350{
5351 PyObject *result = NULL;
5352 int name;
5353
5354 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5355 int value;
5356
5357 errno = 0;
5358 value = sysconf(name);
5359 if (value == -1 && errno != 0)
5360 posix_error();
5361 else
5362 result = PyInt_FromLong(value);
5363 }
5364 return result;
5365}
5366#endif
5367
5368
Fred Drakebec628d1999-12-15 18:31:10 +00005369/* This code is used to ensure that the tables of configuration value names
5370 * are in sorted order as required by conv_confname(), and also to build the
5371 * the exported dictionaries that are used to publish information about the
5372 * names available on the host platform.
5373 *
5374 * Sorting the table at runtime ensures that the table is properly ordered
5375 * when used, even for platforms we're not able to test on. It also makes
5376 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005377 */
Fred Drakebec628d1999-12-15 18:31:10 +00005378
5379static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005380cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005381{
5382 const struct constdef *c1 =
5383 (const struct constdef *) v1;
5384 const struct constdef *c2 =
5385 (const struct constdef *) v2;
5386
5387 return strcmp(c1->name, c2->name);
5388}
5389
5390static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005391setup_confname_table(struct constdef *table, size_t tablesize,
5392 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005393{
Fred Drakebec628d1999-12-15 18:31:10 +00005394 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005395 size_t i;
5396 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005397
5398 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5399 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005400 if (d == NULL)
5401 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005402
Barry Warsaw3155db32000-04-13 15:20:40 +00005403 for (i=0; i < tablesize; ++i) {
5404 PyObject *o = PyInt_FromLong(table[i].value);
5405 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5406 Py_XDECREF(o);
5407 Py_DECREF(d);
5408 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005409 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005410 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005411 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005412 status = PyDict_SetItemString(moddict, tablename, d);
5413 Py_DECREF(d);
5414 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005415}
5416
Fred Drakebec628d1999-12-15 18:31:10 +00005417/* Return -1 on failure, 0 on success. */
5418static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005419setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005420{
5421#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005422 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005423 sizeof(posix_constants_pathconf)
5424 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005425 "pathconf_names", moddict))
5426 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005427#endif
5428#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005429 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005430 sizeof(posix_constants_confstr)
5431 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005432 "confstr_names", moddict))
5433 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005434#endif
5435#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005436 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005437 sizeof(posix_constants_sysconf)
5438 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005439 "sysconf_names", moddict))
5440 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005441#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005442 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005443}
Fred Draked86ed291999-12-15 15:34:33 +00005444
5445
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005446static char posix_abort__doc__[] = "\
5447abort() -> does not return!\n\
5448Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5449in the hardest way possible on the hosting operating system.";
5450
5451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005452posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005453{
5454 if (!PyArg_ParseTuple(args, ":abort"))
5455 return NULL;
5456 abort();
5457 /*NOTREACHED*/
5458 Py_FatalError("abort() called from Python code didn't abort!");
5459 return NULL;
5460}
Fred Drakebec628d1999-12-15 18:31:10 +00005461
Tim Petersf58a7aa2000-09-22 10:05:54 +00005462#ifdef MS_WIN32
5463static char win32_startfile__doc__[] = "\
5464startfile(filepath) - Start a file with its associated application.\n\
5465\n\
5466This acts like double-clicking the file in Explorer, or giving the file\n\
5467name as an argument to the DOS \"start\" command: the file is opened\n\
5468with whatever application (if any) its extension is associated.\n\
5469\n\
5470startfile returns as soon as the associated application is launched.\n\
5471There is no option to wait for the application to close, and no way\n\
5472to retrieve the application's exit status.\n\
5473\n\
5474The filepath is relative to the current directory. If you want to use\n\
5475an absolute path, make sure the first character is not a slash (\"/\");\n\
5476the underlying Win32 ShellExecute function doesn't work if it is.";
5477
5478static PyObject *
5479win32_startfile(PyObject *self, PyObject *args)
5480{
5481 char *filepath;
5482 HINSTANCE rc;
5483 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5484 return NULL;
5485 Py_BEGIN_ALLOW_THREADS
5486 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5487 Py_END_ALLOW_THREADS
5488 if (rc <= (HINSTANCE)32)
5489 return win32_error("startfile", filepath);
5490 Py_INCREF(Py_None);
5491 return Py_None;
5492}
5493#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005494
5495static PyMethodDef posix_methods[] = {
5496 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5497#ifdef HAVE_TTYNAME
5498 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5499#endif
5500 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5501 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005502#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005503 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005504#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005505#ifdef HAVE_CHROOT
5506 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5507#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005508#ifdef HAVE_CTERMID
5509 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5510#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005511#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005512 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005513#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005514#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005515 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005516#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005517 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5518 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5519 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005520#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005521 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005522#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005523#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005524 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005525#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005526 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5527 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5528 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005529#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005530 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005531#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005532#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005533 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005534#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005535 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005536#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005537 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005538#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005539 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5540 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5541 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005542#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005543 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005544#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005545 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005546#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005547 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5548 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005549#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005550#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005551 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5552 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005553#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005554#ifdef HAVE_FORK1
5555 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5556#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005557#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005558 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005559#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005560#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005561 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005562#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005563#ifdef HAVE_FORKPTY
5564 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5565#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005566#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005567 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005568#endif /* HAVE_GETEGID */
5569#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005570 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005571#endif /* HAVE_GETEUID */
5572#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005573 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005574#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005575#ifdef HAVE_GETGROUPS
5576 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5577#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005578 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005579#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005580 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005581#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005582#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005583 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005584#endif /* HAVE_GETPPID */
5585#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005586 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005587#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005588#ifdef HAVE_GETLOGIN
5589 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5590#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005591#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005592 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005593#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00005594#ifdef HAVE_KILLPG
5595 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
5596#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00005597#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005598 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005599#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005600#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005601 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005602#ifdef MS_WIN32
5603 {"popen2", win32_popen2, METH_VARARGS},
5604 {"popen3", win32_popen3, METH_VARARGS},
5605 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005606 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005607#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005608#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005609#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005610 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005611#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005612#ifdef HAVE_SETEUID
5613 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5614#endif /* HAVE_SETEUID */
5615#ifdef HAVE_SETEGID
5616 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5617#endif /* HAVE_SETEGID */
5618#ifdef HAVE_SETREUID
5619 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5620#endif /* HAVE_SETREUID */
5621#ifdef HAVE_SETREGID
5622 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5623#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005624#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005625 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005626#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005627#ifdef HAVE_SETGROUPS
5628 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5629#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005630#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005631 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005632#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005633#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005634 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005635#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00005636#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005637 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005638#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005639#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005640 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005641#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005642#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005643 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005644#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005645#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005646 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005647#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005648#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005649 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005650#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005651 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5652 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5653 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5654 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5655 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5656 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5657 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5658 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5659 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005660 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005661#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005662 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005663#endif
5664#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005665 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005666#endif
5667#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005668 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005669#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005670#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005671 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005672#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005673#ifdef HAVE_UNSETENV
5674 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
5675#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005676#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005677 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005678#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005679#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005680 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005681#endif
5682#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005683 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005684#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005685#ifdef HAVE_SYS_WAIT_H
5686#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005687 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005688#endif /* WIFSTOPPED */
5689#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005690 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005691#endif /* WIFSIGNALED */
5692#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005693 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005694#endif /* WIFEXITED */
5695#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005696 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005697#endif /* WEXITSTATUS */
5698#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005699 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005700#endif /* WTERMSIG */
5701#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005702 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005703#endif /* WSTOPSIG */
5704#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005705#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005706 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005707#endif
5708#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005709 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005710#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005711#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005712 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5713#endif
5714#ifdef HAVE_TEMPNAM
5715 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5716#endif
5717#ifdef HAVE_TMPNAM
5718 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5719#endif
Fred Drakec9680921999-12-13 16:37:25 +00005720#ifdef HAVE_CONFSTR
5721 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5722#endif
5723#ifdef HAVE_SYSCONF
5724 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5725#endif
5726#ifdef HAVE_FPATHCONF
5727 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5728#endif
5729#ifdef HAVE_PATHCONF
5730 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5731#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005732 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005733#ifdef MS_WIN32
5734 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5735#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005736 {NULL, NULL} /* Sentinel */
5737};
5738
5739
Barry Warsaw4a342091996-12-19 23:50:02 +00005740static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005741ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005742{
5743 PyObject* v = PyInt_FromLong(value);
5744 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5745 return -1; /* triggers fatal error */
5746
5747 Py_DECREF(v);
5748 return 0;
5749}
5750
Guido van Rossumd48f2521997-12-05 22:19:34 +00005751#if defined(PYOS_OS2)
5752/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5753static int insertvalues(PyObject *d)
5754{
5755 APIRET rc;
5756 ULONG values[QSV_MAX+1];
5757 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00005758 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00005759
5760 Py_BEGIN_ALLOW_THREADS
5761 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5762 Py_END_ALLOW_THREADS
5763
5764 if (rc != NO_ERROR) {
5765 os2_error(rc);
5766 return -1;
5767 }
5768
5769 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5770 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5771 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5772 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5773 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5774 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5775 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5776
5777 switch (values[QSV_VERSION_MINOR]) {
5778 case 0: ver = "2.00"; break;
5779 case 10: ver = "2.10"; break;
5780 case 11: ver = "2.11"; break;
5781 case 30: ver = "3.00"; break;
5782 case 40: ver = "4.00"; break;
5783 case 50: ver = "5.00"; break;
5784 default:
Tim Peters885d4572001-11-28 20:27:42 +00005785 PyOS_snprintf(tmp, sizeof(tmp),
5786 "%d-%d", values[QSV_VERSION_MAJOR],
5787 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005788 ver = &tmp[0];
5789 }
5790
5791 /* Add Indicator of the Version of the Operating System */
5792 v = PyString_FromString(ver);
5793 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5794 return -1;
5795 Py_DECREF(v);
5796
5797 /* Add Indicator of Which Drive was Used to Boot the System */
5798 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5799 tmp[1] = ':';
5800 tmp[2] = '\0';
5801
5802 v = PyString_FromString(tmp);
5803 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5804 return -1;
5805 Py_DECREF(v);
5806
5807 return 0;
5808}
5809#endif
5810
Barry Warsaw4a342091996-12-19 23:50:02 +00005811static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005812all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005813{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005814#ifdef F_OK
5815 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005816#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005817#ifdef R_OK
5818 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005819#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005820#ifdef W_OK
5821 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005822#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005823#ifdef X_OK
5824 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005825#endif
Fred Drakec9680921999-12-13 16:37:25 +00005826#ifdef NGROUPS_MAX
5827 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5828#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005829#ifdef TMP_MAX
5830 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5831#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005832#ifdef WNOHANG
5833 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005834#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005835#ifdef O_RDONLY
5836 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5837#endif
5838#ifdef O_WRONLY
5839 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5840#endif
5841#ifdef O_RDWR
5842 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5843#endif
5844#ifdef O_NDELAY
5845 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5846#endif
5847#ifdef O_NONBLOCK
5848 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5849#endif
5850#ifdef O_APPEND
5851 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5852#endif
5853#ifdef O_DSYNC
5854 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5855#endif
5856#ifdef O_RSYNC
5857 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5858#endif
5859#ifdef O_SYNC
5860 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5861#endif
5862#ifdef O_NOCTTY
5863 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5864#endif
5865#ifdef O_CREAT
5866 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5867#endif
5868#ifdef O_EXCL
5869 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5870#endif
5871#ifdef O_TRUNC
5872 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5873#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005874#ifdef O_BINARY
5875 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5876#endif
5877#ifdef O_TEXT
5878 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5879#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005880#ifdef O_LARGEFILE
5881 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
5882#endif
5883
Tim Peters5aa91602002-01-30 05:46:57 +00005884/* MS Windows */
5885#ifdef O_NOINHERIT
5886 /* Don't inherit in child processes. */
5887 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
5888#endif
5889#ifdef _O_SHORT_LIVED
5890 /* Optimize for short life (keep in memory). */
5891 /* MS forgot to define this one with a non-underscore form too. */
5892 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
5893#endif
5894#ifdef O_TEMPORARY
5895 /* Automatically delete when last handle is closed. */
5896 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
5897#endif
5898#ifdef O_RANDOM
5899 /* Optimize for random access. */
5900 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
5901#endif
5902#ifdef O_SEQUENTIAL
5903 /* Optimize for sequential access. */
5904 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
5905#endif
5906
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005907/* GNU extensions. */
5908#ifdef O_DIRECT
5909 /* Direct disk access. */
5910 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
5911#endif
5912#ifdef O_DIRECTORY
5913 /* Must be a directory. */
5914 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
5915#endif
5916#ifdef O_NOFOLLOW
5917 /* Do not follow links. */
5918 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
5919#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005920
Guido van Rossum246bc171999-02-01 23:54:31 +00005921#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005922 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5923 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5924 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5925 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5926 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005927#endif
5928
Guido van Rossumd48f2521997-12-05 22:19:34 +00005929#if defined(PYOS_OS2)
5930 if (insertvalues(d)) return -1;
5931#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005932 return 0;
5933}
5934
5935
Tim Peters5aa91602002-01-30 05:46:57 +00005936#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005937#define INITFUNC initnt
5938#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005939
5940#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005941#define INITFUNC initos2
5942#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005943
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005944#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005945#define INITFUNC initposix
5946#define MODNAME "posix"
5947#endif
5948
Guido van Rossum3886bb61998-12-04 18:50:17 +00005949DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005950INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005951{
Barry Warsaw53699e91996-12-10 23:23:01 +00005952 PyObject *m, *d, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00005953
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005954 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005955 posix_methods,
5956 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005957 (PyObject *)NULL,
5958 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005959 d = PyModule_GetDict(m);
Tim Peters5aa91602002-01-30 05:46:57 +00005960
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005961 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005962 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005963 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005964 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005965 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005966
Barry Warsaw4a342091996-12-19 23:50:02 +00005967 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005968 return;
5969
Fred Drakebec628d1999-12-15 18:31:10 +00005970 if (setup_confname_tables(d))
5971 return;
5972
Barry Warsawca74da41999-02-09 19:31:45 +00005973 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005974
Guido van Rossumb3d39562000-01-31 18:41:26 +00005975#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005976 if (posix_putenv_garbage == NULL)
5977 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005978#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005979
Guido van Rossum14648392001-12-08 18:02:58 +00005980 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005981 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
5982 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
5983
Guido van Rossum14648392001-12-08 18:02:58 +00005984 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005985 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Guido van Rossumbb2501f2001-12-27 16:23:28 +00005986 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005987}