blob: 31c991cc7d4f36e9ec7d47d7c4d29691973785b6 [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
Guido van Rossumc0125471996-06-28 18:55:32 +00002202#ifdef HAVE_PLOCK
2203
2204#ifdef HAVE_SYS_LOCK_H
2205#include <sys/lock.h>
2206#endif
2207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002208static char posix_plock__doc__[] =
2209"plock(op) -> None\n\
2210Lock program segments into memory.";
2211
Barry Warsaw53699e91996-12-10 23:23:01 +00002212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002213posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002214{
2215 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002216 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002217 return NULL;
2218 if (plock(op) == -1)
2219 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002220 Py_INCREF(Py_None);
2221 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002222}
2223#endif
2224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002225
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002226#ifdef HAVE_POPEN
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002227static char posix_popen__doc__[] =
2228"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2229Open a pipe to/from a command returning a file object.";
2230
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002231#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002232static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002233async_system(const char *command)
2234{
2235 char *p, errormsg[256], args[1024];
2236 RESULTCODES rcodes;
2237 APIRET rc;
2238 char *shell = getenv("COMSPEC");
2239 if (!shell)
2240 shell = "cmd";
2241
2242 strcpy(args, shell);
2243 p = &args[ strlen(args)+1 ];
2244 strcpy(p, "/c ");
2245 strcat(p, command);
2246 p += strlen(p) + 1;
2247 *p = '\0';
2248
2249 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002250 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002251 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002252 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002253 &rcodes, shell);
2254 return rc;
2255}
2256
Guido van Rossumd48f2521997-12-05 22:19:34 +00002257static FILE *
2258popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002259{
2260 HFILE rhan, whan;
2261 FILE *retfd = NULL;
2262 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2263
Guido van Rossumd48f2521997-12-05 22:19:34 +00002264 if (rc != NO_ERROR) {
2265 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002266 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002267 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002268
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002269 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2270 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002271
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002272 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2273 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002274
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002275 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2276 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002277
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002278 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002279 }
2280
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002281 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2282 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002284 if (rc == NO_ERROR)
2285 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2286
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002287 close(oldfd); /* And Close Saved STDOUT Handle */
2288 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002289
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002290 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2291 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002292
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002293 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2294 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002295
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002296 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2297 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002298
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002299 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002300 }
2301
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002302 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2303 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002304
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002305 if (rc == NO_ERROR)
2306 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2307
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002308 close(oldfd); /* And Close Saved STDIN Handle */
2309 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002310
Guido van Rossumd48f2521997-12-05 22:19:34 +00002311 } else {
2312 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002313 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002314 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002315}
2316
2317static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002318posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002319{
2320 char *name;
2321 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002322 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323 FILE *fp;
2324 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002325 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002326 return NULL;
2327 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002328 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002329 Py_END_ALLOW_THREADS
2330 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002331 return os2_error(err);
2332
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002333 f = PyFile_FromFile(fp, name, mode, fclose);
2334 if (f != NULL)
2335 PyFile_SetBufSize(f, bufsize);
2336 return f;
2337}
2338
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002339#elif defined(MS_WIN32)
2340
2341/*
2342 * Portable 'popen' replacement for Win32.
2343 *
2344 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2345 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00002346 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002347 */
2348
2349#include <malloc.h>
2350#include <io.h>
2351#include <fcntl.h>
2352
2353/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2354#define POPEN_1 1
2355#define POPEN_2 2
2356#define POPEN_3 3
2357#define POPEN_4 4
2358
2359static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002360static int _PyPclose(FILE *file);
2361
2362/*
2363 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00002364 * for use when retrieving the process exit code. See _PyPclose() below
2365 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002366 */
2367static PyObject *_PyPopenProcs = NULL;
2368
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002369
2370/* popen that works from a GUI.
2371 *
2372 * The result of this function is a pipe (file) connected to the
2373 * processes stdin or stdout, depending on the requested mode.
2374 */
2375
2376static PyObject *
2377posix_popen(PyObject *self, PyObject *args)
2378{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002379 PyObject *f, *s;
2380 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00002381
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002382 char *cmdstring;
2383 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002384 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002385 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002386 return NULL;
2387
2388 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00002389
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002390 if (*mode == 'r')
2391 tm = _O_RDONLY;
2392 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00002393 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002394 return NULL;
2395 } else
2396 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00002397
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002398 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002399 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002400 return NULL;
2401 }
2402
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002403 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002404 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002405 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002406 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002407 else
2408 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2409
2410 return f;
2411}
2412
2413/* Variation on win32pipe.popen
2414 *
2415 * The result of this function is a pipe (file) connected to the
2416 * process's stdin, and a pipe connected to the process's stdout.
2417 */
2418
2419static PyObject *
2420win32_popen2(PyObject *self, PyObject *args)
2421{
2422 PyObject *f;
2423 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00002424
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002425 char *cmdstring;
2426 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002427 int bufsize = -1;
2428 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002429 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002430
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002431 if (*mode == 't')
2432 tm = _O_TEXT;
2433 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002434 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002435 return NULL;
2436 } else
2437 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00002438
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002439 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002440 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002441 return NULL;
2442 }
2443
2444 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00002445
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002446 return f;
2447}
2448
2449/*
2450 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002451 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002452 * The result of this function is 3 pipes - the process's stdin,
2453 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002454 */
2455
2456static PyObject *
2457win32_popen3(PyObject *self, PyObject *args)
2458{
2459 PyObject *f;
2460 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00002461
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002462 char *cmdstring;
2463 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002464 int bufsize = -1;
2465 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002466 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002467
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002468 if (*mode == 't')
2469 tm = _O_TEXT;
2470 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002471 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002472 return NULL;
2473 } else
2474 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00002475
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002476 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002477 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002478 return NULL;
2479 }
2480
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002481 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00002482
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002483 return f;
2484}
2485
2486/*
2487 * Variation on win32pipe.popen
2488 *
Tim Peters5aa91602002-01-30 05:46:57 +00002489 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002490 * and stdout+stderr combined as a single pipe.
2491 */
2492
2493static PyObject *
2494win32_popen4(PyObject *self, PyObject *args)
2495{
2496 PyObject *f;
2497 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00002498
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002499 char *cmdstring;
2500 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002501 int bufsize = -1;
2502 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002503 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002504
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002505 if (*mode == 't')
2506 tm = _O_TEXT;
2507 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00002508 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002509 return NULL;
2510 } else
2511 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002512
2513 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00002514 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002515 return NULL;
2516 }
2517
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00002518 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00002519
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002520 return f;
2521}
2522
Mark Hammond08501372001-01-31 07:30:29 +00002523static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00002524_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002525 HANDLE hStdin,
2526 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00002527 HANDLE hStderr,
2528 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002529{
2530 PROCESS_INFORMATION piProcInfo;
2531 STARTUPINFO siStartInfo;
2532 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00002533 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002534 int i;
2535 int x;
2536
2537 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00002538 char *comshell;
2539
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002540 s1 = (char *)_alloca(i);
2541 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2542 return x;
Tim Peters402d5982001-08-27 06:37:48 +00002543
2544 /* Explicitly check if we are using COMMAND.COM. If we are
2545 * then use the w9xpopen hack.
2546 */
2547 comshell = s1 + x;
2548 while (comshell >= s1 && *comshell != '\\')
2549 --comshell;
2550 ++comshell;
2551
2552 if (GetVersion() < 0x80000000 &&
2553 _stricmp(comshell, "command.com") != 0) {
2554 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002555 x = i + strlen(s3) + strlen(cmdstring) + 1;
2556 s2 = (char *)_alloca(x);
2557 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002558 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002559 }
2560 else {
2561 /*
Tim Peters402d5982001-08-27 06:37:48 +00002562 * Oh gag, we're on Win9x or using COMMAND.COM. Use
2563 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002564 */
Mark Hammond08501372001-01-31 07:30:29 +00002565 char modulepath[_MAX_PATH];
2566 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002567 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2568 for (i = x = 0; modulepath[i]; i++)
2569 if (modulepath[i] == '\\')
2570 x = i+1;
2571 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00002572 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00002573 strncat(modulepath,
2574 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00002575 (sizeof(modulepath)/sizeof(modulepath[0]))
2576 -strlen(modulepath));
2577 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002578 /* Eeek - file-not-found - possibly an embedding
2579 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00002580 */
Tim Peters5aa91602002-01-30 05:46:57 +00002581 strncpy(modulepath,
2582 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00002583 sizeof(modulepath)/sizeof(modulepath[0]));
2584 if (modulepath[strlen(modulepath)-1] != '\\')
2585 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00002586 strncat(modulepath,
2587 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00002588 (sizeof(modulepath)/sizeof(modulepath[0]))
2589 -strlen(modulepath));
2590 /* No where else to look - raise an easily identifiable
2591 error, rather than leaving Windows to report
2592 "file not found" - as the user is probably blissfully
2593 unaware this shim EXE is used, and it will confuse them.
2594 (well, it confused me for a while ;-)
2595 */
2596 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002597 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00002598 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00002599 "for popen to work with your shell "
2600 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00002601 szConsoleSpawn);
2602 return FALSE;
2603 }
2604 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002605 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00002606 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002607 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00002608
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002609 s2 = (char *)_alloca(x);
2610 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00002611 PyOS_snprintf(
2612 s2, x,
Mark Hammond08501372001-01-31 07:30:29 +00002613 "%s \"%s%s%s\"",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002614 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002615 s1,
2616 s3,
2617 cmdstring);
2618 }
2619 }
2620
2621 /* Could be an else here to try cmd.exe / command.com in the path
2622 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00002623 else {
Tim Peters402d5982001-08-27 06:37:48 +00002624 PyErr_SetString(PyExc_RuntimeError,
2625 "Cannot locate a COMSPEC environment variable to "
2626 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00002627 return FALSE;
2628 }
Tim Peters5aa91602002-01-30 05:46:57 +00002629
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002630 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2631 siStartInfo.cb = sizeof(STARTUPINFO);
2632 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2633 siStartInfo.hStdInput = hStdin;
2634 siStartInfo.hStdOutput = hStdout;
2635 siStartInfo.hStdError = hStderr;
2636 siStartInfo.wShowWindow = SW_HIDE;
2637
2638 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002639 s2,
2640 NULL,
2641 NULL,
2642 TRUE,
2643 CREATE_NEW_CONSOLE,
2644 NULL,
2645 NULL,
2646 &siStartInfo,
2647 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002648 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002649 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002650
Mark Hammondb37a3732000-08-14 04:47:33 +00002651 /* Return process handle */
2652 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002653 return TRUE;
2654 }
Tim Peters402d5982001-08-27 06:37:48 +00002655 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002656 return FALSE;
2657}
2658
2659/* The following code is based off of KB: Q190351 */
2660
2661static PyObject *
2662_PyPopen(char *cmdstring, int mode, int n)
2663{
2664 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2665 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00002666 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00002667
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002668 SECURITY_ATTRIBUTES saAttr;
2669 BOOL fSuccess;
2670 int fd1, fd2, fd3;
2671 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00002672 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002673 PyObject *f;
2674
2675 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2676 saAttr.bInheritHandle = TRUE;
2677 saAttr.lpSecurityDescriptor = NULL;
2678
2679 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2680 return win32_error("CreatePipe", NULL);
2681
2682 /* Create new output read handle and the input write handle. Set
2683 * the inheritance properties to FALSE. Otherwise, the child inherits
2684 * the these handles; resulting in non-closeable handles to the pipes
2685 * being created. */
2686 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002687 GetCurrentProcess(), &hChildStdinWrDup, 0,
2688 FALSE,
2689 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002690 if (!fSuccess)
2691 return win32_error("DuplicateHandle", NULL);
2692
2693 /* Close the inheritable version of ChildStdin
2694 that we're using. */
2695 CloseHandle(hChildStdinWr);
2696
2697 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2698 return win32_error("CreatePipe", NULL);
2699
2700 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002701 GetCurrentProcess(), &hChildStdoutRdDup, 0,
2702 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002703 if (!fSuccess)
2704 return win32_error("DuplicateHandle", NULL);
2705
2706 /* Close the inheritable version of ChildStdout
2707 that we're using. */
2708 CloseHandle(hChildStdoutRd);
2709
2710 if (n != POPEN_4) {
2711 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2712 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002713 fSuccess = DuplicateHandle(GetCurrentProcess(),
2714 hChildStderrRd,
2715 GetCurrentProcess(),
2716 &hChildStderrRdDup, 0,
2717 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002718 if (!fSuccess)
2719 return win32_error("DuplicateHandle", NULL);
2720 /* Close the inheritable version of ChildStdErr that we're using. */
2721 CloseHandle(hChildStderrRd);
2722 }
Tim Peters5aa91602002-01-30 05:46:57 +00002723
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002724 switch (n) {
2725 case POPEN_1:
2726 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2727 case _O_WRONLY | _O_TEXT:
2728 /* Case for writing to child Stdin in text mode. */
2729 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2730 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002731 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002732 PyFile_SetBufSize(f, 0);
2733 /* We don't care about these pipes anymore, so close them. */
2734 CloseHandle(hChildStdoutRdDup);
2735 CloseHandle(hChildStderrRdDup);
2736 break;
2737
2738 case _O_RDONLY | _O_TEXT:
2739 /* Case for reading from child Stdout in text mode. */
2740 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2741 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002742 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002743 PyFile_SetBufSize(f, 0);
2744 /* We don't care about these pipes anymore, so close them. */
2745 CloseHandle(hChildStdinWrDup);
2746 CloseHandle(hChildStderrRdDup);
2747 break;
2748
2749 case _O_RDONLY | _O_BINARY:
2750 /* Case for readinig from child Stdout in binary mode. */
2751 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2752 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002753 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002754 PyFile_SetBufSize(f, 0);
2755 /* We don't care about these pipes anymore, so close them. */
2756 CloseHandle(hChildStdinWrDup);
2757 CloseHandle(hChildStderrRdDup);
2758 break;
2759
2760 case _O_WRONLY | _O_BINARY:
2761 /* Case for writing to child Stdin in binary mode. */
2762 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2763 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00002764 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002765 PyFile_SetBufSize(f, 0);
2766 /* We don't care about these pipes anymore, so close them. */
2767 CloseHandle(hChildStdoutRdDup);
2768 CloseHandle(hChildStderrRdDup);
2769 break;
2770 }
Mark Hammondb37a3732000-08-14 04:47:33 +00002771 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002772 break;
Tim Peters5aa91602002-01-30 05:46:57 +00002773
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002774 case POPEN_2:
2775 case POPEN_4:
2776 {
2777 char *m1, *m2;
2778 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00002779
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002780 if (mode && _O_TEXT) {
2781 m1 = "r";
2782 m2 = "w";
2783 } else {
2784 m1 = "rb";
2785 m2 = "wb";
2786 }
2787
2788 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2789 f1 = _fdopen(fd1, m2);
2790 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2791 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002792 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002793 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00002794 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002795 PyFile_SetBufSize(p2, 0);
2796
2797 if (n != 4)
2798 CloseHandle(hChildStderrRdDup);
2799
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002800 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00002801 Py_XDECREF(p1);
2802 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00002803 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002804 break;
2805 }
Tim Peters5aa91602002-01-30 05:46:57 +00002806
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002807 case POPEN_3:
2808 {
2809 char *m1, *m2;
2810 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00002811
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002812 if (mode && _O_TEXT) {
2813 m1 = "r";
2814 m2 = "w";
2815 } else {
2816 m1 = "rb";
2817 m2 = "wb";
2818 }
2819
2820 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2821 f1 = _fdopen(fd1, m2);
2822 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2823 f2 = _fdopen(fd2, m1);
2824 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2825 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00002826 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00002827 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
2828 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002829 PyFile_SetBufSize(p1, 0);
2830 PyFile_SetBufSize(p2, 0);
2831 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002832 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00002833 Py_XDECREF(p1);
2834 Py_XDECREF(p2);
2835 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00002836 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002837 break;
2838 }
2839 }
2840
2841 if (n == POPEN_4) {
2842 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002843 hChildStdinRd,
2844 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002845 hChildStdoutWr,
2846 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002847 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002848 }
2849 else {
2850 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00002851 hChildStdinRd,
2852 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00002853 hChildStderrWr,
2854 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00002855 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002856 }
2857
Mark Hammondb37a3732000-08-14 04:47:33 +00002858 /*
2859 * Insert the files we've created into the process dictionary
2860 * all referencing the list with the process handle and the
2861 * initial number of files (see description below in _PyPclose).
2862 * Since if _PyPclose later tried to wait on a process when all
2863 * handles weren't closed, it could create a deadlock with the
2864 * child, we spend some energy here to try to ensure that we
2865 * either insert all file handles into the dictionary or none
2866 * at all. It's a little clumsy with the various popen modes
2867 * and variable number of files involved.
2868 */
2869 if (!_PyPopenProcs) {
2870 _PyPopenProcs = PyDict_New();
2871 }
2872
2873 if (_PyPopenProcs) {
2874 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
2875 int ins_rc[3];
2876
2877 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2878 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2879
2880 procObj = PyList_New(2);
2881 hProcessObj = PyLong_FromVoidPtr(hProcess);
2882 intObj = PyInt_FromLong(file_count);
2883
2884 if (procObj && hProcessObj && intObj) {
2885 PyList_SetItem(procObj,0,hProcessObj);
2886 PyList_SetItem(procObj,1,intObj);
2887
2888 fileObj[0] = PyLong_FromVoidPtr(f1);
2889 if (fileObj[0]) {
2890 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2891 fileObj[0],
2892 procObj);
2893 }
2894 if (file_count >= 2) {
2895 fileObj[1] = PyLong_FromVoidPtr(f2);
2896 if (fileObj[1]) {
2897 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2898 fileObj[1],
2899 procObj);
2900 }
2901 }
2902 if (file_count >= 3) {
2903 fileObj[2] = PyLong_FromVoidPtr(f3);
2904 if (fileObj[2]) {
2905 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2906 fileObj[2],
2907 procObj);
2908 }
2909 }
2910
2911 if (ins_rc[0] < 0 || !fileObj[0] ||
2912 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2913 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
2914 /* Something failed - remove any dictionary
2915 * entries that did make it.
2916 */
2917 if (!ins_rc[0] && fileObj[0]) {
2918 PyDict_DelItem(_PyPopenProcs,
2919 fileObj[0]);
2920 }
2921 if (!ins_rc[1] && fileObj[1]) {
2922 PyDict_DelItem(_PyPopenProcs,
2923 fileObj[1]);
2924 }
2925 if (!ins_rc[2] && fileObj[2]) {
2926 PyDict_DelItem(_PyPopenProcs,
2927 fileObj[2]);
2928 }
2929 }
2930 }
Tim Peters5aa91602002-01-30 05:46:57 +00002931
Mark Hammondb37a3732000-08-14 04:47:33 +00002932 /*
2933 * Clean up our localized references for the dictionary keys
2934 * and value since PyDict_SetItem will Py_INCREF any copies
2935 * that got placed in the dictionary.
2936 */
2937 Py_XDECREF(procObj);
2938 Py_XDECREF(fileObj[0]);
2939 Py_XDECREF(fileObj[1]);
2940 Py_XDECREF(fileObj[2]);
2941 }
2942
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002943 /* Child is launched. Close the parents copy of those pipe
2944 * handles that only the child should have open. You need to
2945 * make sure that no handles to the write end of the output pipe
2946 * are maintained in this process or else the pipe will not close
2947 * when the child process exits and the ReadFile will hang. */
2948
2949 if (!CloseHandle(hChildStdinRd))
2950 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00002951
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002952 if (!CloseHandle(hChildStdoutWr))
2953 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00002954
Fredrik Lundhffb9c772000-07-09 14:49:51 +00002955 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2956 return win32_error("CloseHandle", NULL);
2957
2958 return f;
2959}
Fredrik Lundh56055a42000-07-23 19:47:12 +00002960
2961/*
2962 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2963 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00002964 *
2965 * This function uses the _PyPopenProcs dictionary in order to map the
2966 * input file pointer to information about the process that was
2967 * originally created by the popen* call that created the file pointer.
2968 * The dictionary uses the file pointer as a key (with one entry
2969 * inserted for each file returned by the original popen* call) and a
2970 * single list object as the value for all files from a single call.
2971 * The list object contains the Win32 process handle at [0], and a file
2972 * count at [1], which is initialized to the total number of file
2973 * handles using that list.
2974 *
2975 * This function closes whichever handle it is passed, and decrements
2976 * the file count in the dictionary for the process handle pointed to
2977 * by this file. On the last close (when the file count reaches zero),
2978 * this function will wait for the child process and then return its
2979 * exit code as the result of the close() operation. This permits the
2980 * files to be closed in any order - it is always the close() of the
2981 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00002982 */
Tim Peters736aa322000-09-01 06:51:24 +00002983
2984 /* RED_FLAG 31-Aug-2000 Tim
2985 * This is always called (today!) between a pair of
2986 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2987 * macros. So the thread running this has no valid thread state, as
2988 * far as Python is concerned. However, this calls some Python API
2989 * functions that cannot be called safely without a valid thread
2990 * state, in particular PyDict_GetItem.
2991 * As a temporary hack (although it may last for years ...), we
2992 * *rely* on not having a valid thread state in this function, in
2993 * order to create our own "from scratch".
2994 * This will deadlock if _PyPclose is ever called by a thread
2995 * holding the global lock.
2996 */
2997
Fredrik Lundh56055a42000-07-23 19:47:12 +00002998static int _PyPclose(FILE *file)
2999{
Fredrik Lundh20318932000-07-26 17:29:12 +00003000 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003001 DWORD exit_code;
3002 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003003 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3004 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003005#ifdef WITH_THREAD
3006 PyInterpreterState* pInterpreterState;
3007 PyThreadState* pThreadState;
3008#endif
3009
Fredrik Lundh20318932000-07-26 17:29:12 +00003010 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003011 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003012 */
3013 result = fclose(file);
3014
Tim Peters736aa322000-09-01 06:51:24 +00003015#ifdef WITH_THREAD
3016 /* Bootstrap a valid thread state into existence. */
3017 pInterpreterState = PyInterpreterState_New();
3018 if (!pInterpreterState) {
3019 /* Well, we're hosed now! We don't have a thread
3020 * state, so can't call a nice error routine, or raise
3021 * an exception. Just die.
3022 */
3023 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003024 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003025 return -1; /* unreachable */
3026 }
3027 pThreadState = PyThreadState_New(pInterpreterState);
3028 if (!pThreadState) {
3029 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003030 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003031 return -1; /* unreachable */
3032 }
3033 /* Grab the global lock. Note that this will deadlock if the
3034 * current thread already has the lock! (see RED_FLAG comments
3035 * before this function)
3036 */
3037 PyEval_RestoreThread(pThreadState);
3038#endif
3039
Fredrik Lundh56055a42000-07-23 19:47:12 +00003040 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003041 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3042 (procObj = PyDict_GetItem(_PyPopenProcs,
3043 fileObj)) != NULL &&
3044 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3045 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3046
3047 hProcess = PyLong_AsVoidPtr(hProcessObj);
3048 file_count = PyInt_AsLong(intObj);
3049
3050 if (file_count > 1) {
3051 /* Still other files referencing process */
3052 file_count--;
3053 PyList_SetItem(procObj,1,
3054 PyInt_FromLong(file_count));
3055 } else {
3056 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003057 if (result != EOF &&
3058 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3059 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003060 /* Possible truncation here in 16-bit environments, but
3061 * real exit codes are just the lower byte in any event.
3062 */
3063 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003064 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003065 /* Indicate failure - this will cause the file object
3066 * to raise an I/O error and translate the last Win32
3067 * error code from errno. We do have a problem with
3068 * last errors that overlap the normal errno table,
3069 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003070 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003071 if (result != EOF) {
3072 /* If the error wasn't from the fclose(), then
3073 * set errno for the file object error handling.
3074 */
3075 errno = GetLastError();
3076 }
3077 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003078 }
3079
3080 /* Free up the native handle at this point */
3081 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003082 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003083
Mark Hammondb37a3732000-08-14 04:47:33 +00003084 /* Remove this file pointer from dictionary */
3085 PyDict_DelItem(_PyPopenProcs, fileObj);
3086
3087 if (PyDict_Size(_PyPopenProcs) == 0) {
3088 Py_DECREF(_PyPopenProcs);
3089 _PyPopenProcs = NULL;
3090 }
3091
3092 } /* if object retrieval ok */
3093
3094 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003095 } /* if _PyPopenProcs */
3096
Tim Peters736aa322000-09-01 06:51:24 +00003097#ifdef WITH_THREAD
3098 /* Tear down the thread & interpreter states.
3099 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003100 * call the thread clear & delete functions, and indeed insist on
3101 * doing that themselves. The lock must be held during the clear, but
3102 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003103 */
3104 PyInterpreterState_Clear(pInterpreterState);
3105 PyEval_ReleaseThread(pThreadState);
3106 PyInterpreterState_Delete(pInterpreterState);
3107#endif
3108
Fredrik Lundh56055a42000-07-23 19:47:12 +00003109 return result;
3110}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003111
3112#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003114posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003115{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003116 char *name;
3117 char *mode = "r";
3118 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003119 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003120 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003121 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003122 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003123 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003124 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003125 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003126 if (fp == NULL)
3127 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003128 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003129 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003130 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003131 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003132}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003133#endif
3134
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003135#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003137
Guido van Rossumb6775db1994-08-01 11:34:53 +00003138#ifdef HAVE_SETUID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003139static char posix_setuid__doc__[] =
3140"setuid(uid) -> None\n\
3141Set the current process's user id.";
Barry Warsaw53699e91996-12-10 23:23:01 +00003142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003143posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003144{
3145 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003146 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003147 return NULL;
3148 if (setuid(uid) < 0)
3149 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003150 Py_INCREF(Py_None);
3151 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003152}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003153#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003156#ifdef HAVE_SETEUID
3157static char posix_seteuid__doc__[] =
3158"seteuid(uid) -> None\n\
3159Set the current process's effective user id.";
3160static PyObject *
3161posix_seteuid (PyObject *self, PyObject *args)
3162{
3163 int euid;
3164 if (!PyArg_ParseTuple(args, "i", &euid)) {
3165 return NULL;
3166 } else if (seteuid(euid) < 0) {
3167 return posix_error();
3168 } else {
3169 Py_INCREF(Py_None);
3170 return Py_None;
3171 }
3172}
3173#endif /* HAVE_SETEUID */
3174
3175#ifdef HAVE_SETEGID
3176static char posix_setegid__doc__[] =
3177"setegid(gid) -> None\n\
3178Set the current process's effective group id.";
3179static PyObject *
3180posix_setegid (PyObject *self, PyObject *args)
3181{
3182 int egid;
3183 if (!PyArg_ParseTuple(args, "i", &egid)) {
3184 return NULL;
3185 } else if (setegid(egid) < 0) {
3186 return posix_error();
3187 } else {
3188 Py_INCREF(Py_None);
3189 return Py_None;
3190 }
3191}
3192#endif /* HAVE_SETEGID */
3193
3194#ifdef HAVE_SETREUID
3195static char posix_setreuid__doc__[] =
3196"seteuid(ruid, euid) -> None\n\
3197Set the current process's real and effective user ids.";
3198static PyObject *
3199posix_setreuid (PyObject *self, PyObject *args)
3200{
3201 int ruid, euid;
3202 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3203 return NULL;
3204 } else if (setreuid(ruid, euid) < 0) {
3205 return posix_error();
3206 } else {
3207 Py_INCREF(Py_None);
3208 return Py_None;
3209 }
3210}
3211#endif /* HAVE_SETREUID */
3212
3213#ifdef HAVE_SETREGID
3214static char posix_setregid__doc__[] =
3215"setegid(rgid, egid) -> None\n\
3216Set the current process's real and effective group ids.";
3217static PyObject *
3218posix_setregid (PyObject *self, PyObject *args)
3219{
3220 int rgid, egid;
3221 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3222 return NULL;
3223 } else if (setregid(rgid, egid) < 0) {
3224 return posix_error();
3225 } else {
3226 Py_INCREF(Py_None);
3227 return Py_None;
3228 }
3229}
3230#endif /* HAVE_SETREGID */
3231
Guido van Rossumb6775db1994-08-01 11:34:53 +00003232#ifdef HAVE_SETGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003233static char posix_setgid__doc__[] =
3234"setgid(gid) -> None\n\
3235Set the current process's group id.";
3236
Barry Warsaw53699e91996-12-10 23:23:01 +00003237static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003238posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003239{
3240 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003241 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003242 return NULL;
3243 if (setgid(gid) < 0)
3244 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003245 Py_INCREF(Py_None);
3246 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003247}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003248#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003249
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003250#ifdef HAVE_SETGROUPS
3251static char posix_setgroups__doc__[] =
3252"setgroups(list) -> None\n\
3253Set the groups of the current process to list.";
3254
3255static PyObject *
3256posix_setgroups(PyObject *self, PyObject *args)
3257{
3258 PyObject *groups;
3259 int i, len;
3260 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003261
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003262 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3263 return NULL;
3264 if (!PySequence_Check(groups)) {
3265 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3266 return NULL;
3267 }
3268 len = PySequence_Size(groups);
3269 if (len > MAX_GROUPS) {
3270 PyErr_SetString(PyExc_ValueError, "too many groups");
3271 return NULL;
3272 }
3273 for(i = 0; i < len; i++) {
3274 PyObject *elem;
3275 elem = PySequence_GetItem(groups, i);
3276 if (!elem)
3277 return NULL;
3278 if (!PyInt_Check(elem)) {
3279 PyErr_SetString(PyExc_TypeError,
3280 "groups must be integers");
3281 Py_DECREF(elem);
3282 return NULL;
3283 }
3284 /* XXX: check that value fits into gid_t. */
3285 grouplist[i] = PyInt_AsLong(elem);
3286 Py_DECREF(elem);
3287 }
3288
3289 if (setgroups(len, grouplist) < 0)
3290 return posix_error();
3291 Py_INCREF(Py_None);
3292 return Py_None;
3293}
3294#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003295
Guido van Rossumb6775db1994-08-01 11:34:53 +00003296#ifdef HAVE_WAITPID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003297static char posix_waitpid__doc__[] =
3298"waitpid(pid, options) -> (pid, status)\n\
Guido van Rossumf377d572000-12-12 00:37:58 +00003299Wait for completion of a given child process.";
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003300
Barry Warsaw53699e91996-12-10 23:23:01 +00003301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003302posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003303{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003304 int pid, options;
3305#ifdef UNION_WAIT
3306 union wait status;
3307#define status_i (status.w_status)
3308#else
3309 int status;
3310#define status_i status
3311#endif
3312 status_i = 0;
3313
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003314 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00003315 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003316 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00003317 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00003318 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00003319 if (pid == -1)
3320 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00003321 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003322 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00003323}
3324
Tim Petersab034fa2002-02-01 11:27:43 +00003325#elif defined(HAVE_CWAIT)
3326
3327/* MS C has a variant of waitpid() that's usable for most purposes. */
3328static char posix_waitpid__doc__[] =
3329"waitpid(pid, options) -> (pid, status << 8)\n"
3330"Wait for completion of a given process. options is ignored on Windows.";
3331
3332static PyObject *
3333posix_waitpid(PyObject *self, PyObject *args)
3334{
3335 int pid, options;
3336 int status;
3337
3338 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
3339 return NULL;
3340 Py_BEGIN_ALLOW_THREADS
3341 pid = _cwait(&status, pid, options);
3342 Py_END_ALLOW_THREADS
3343 if (pid == -1)
3344 return posix_error();
3345 else
3346 /* shift the status left a byte so this is more like the
3347 POSIX waitpid */
3348 return Py_BuildValue("ii", pid, status << 8);
3349}
3350#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003351
Guido van Rossumad0ee831995-03-01 10:34:45 +00003352#ifdef HAVE_WAIT
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003353static char posix_wait__doc__[] =
3354"wait() -> (pid, status)\n\
3355Wait for completion of a child process.";
3356
Barry Warsaw53699e91996-12-10 23:23:01 +00003357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003358posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00003359{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003360 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003361#ifdef UNION_WAIT
3362 union wait status;
3363#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003364#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003365 int status;
3366#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00003367#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003368 if (!PyArg_ParseTuple(args, ":wait"))
3369 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003370 status_i = 0;
3371 Py_BEGIN_ALLOW_THREADS
3372 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00003373 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00003374 if (pid == -1)
3375 return posix_error();
3376 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00003377 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003378#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00003379}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003380#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003382
3383static char posix_lstat__doc__[] =
3384"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3385Like stat(path), but do not follow symbolic links.";
3386
Barry Warsaw53699e91996-12-10 23:23:01 +00003387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003388posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003389{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003390#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00003391 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003392#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00003393 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003394#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003395}
3396
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003397
Guido van Rossumb6775db1994-08-01 11:34:53 +00003398#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003399static char posix_readlink__doc__[] =
3400"readlink(path) -> path\n\
3401Return a string representing the path to which the symbolic link points.";
3402
Barry Warsaw53699e91996-12-10 23:23:01 +00003403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003404posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003405{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003406 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003407 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003408 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003409 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003410 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003411 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00003412 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00003413 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003414 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00003415 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00003416 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003417}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003418#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003419
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003420
Guido van Rossumb6775db1994-08-01 11:34:53 +00003421#ifdef HAVE_SYMLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003422static char posix_symlink__doc__[] =
3423"symlink(src, dst) -> None\n\
3424Create a symbolic link.";
3425
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003426static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003427posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003428{
Mark Hammondef8b6542001-05-13 08:04:26 +00003429 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003430}
3431#endif /* HAVE_SYMLINK */
3432
3433
3434#ifdef HAVE_TIMES
3435#ifndef HZ
3436#define HZ 60 /* Universal constant :-) */
3437#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00003438
Guido van Rossumd48f2521997-12-05 22:19:34 +00003439#if defined(PYCC_VACPP) && defined(PYOS_OS2)
3440static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00003441system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003442{
3443 ULONG value = 0;
3444
3445 Py_BEGIN_ALLOW_THREADS
3446 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
3447 Py_END_ALLOW_THREADS
3448
3449 return value;
3450}
3451
3452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003453posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003454{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003455 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00003456 return NULL;
3457
3458 /* Currently Only Uptime is Provided -- Others Later */
3459 return Py_BuildValue("ddddd",
3460 (double)0 /* t.tms_utime / HZ */,
3461 (double)0 /* t.tms_stime / HZ */,
3462 (double)0 /* t.tms_cutime / HZ */,
3463 (double)0 /* t.tms_cstime / HZ */,
3464 (double)system_uptime() / 1000);
3465}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003466#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003468posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00003469{
3470 struct tms t;
3471 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003472 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00003473 return NULL;
3474 errno = 0;
3475 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00003476 if (c == (clock_t) -1)
3477 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003478 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00003479 (double)t.tms_utime / HZ,
3480 (double)t.tms_stime / HZ,
3481 (double)t.tms_cutime / HZ,
3482 (double)t.tms_cstime / HZ,
3483 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00003484}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003485#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003486#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003487
3488
Guido van Rossum87755a21996-09-07 00:59:43 +00003489#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003490#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00003491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003492posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003493{
3494 FILETIME create, exit, kernel, user;
3495 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003496 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003497 return NULL;
3498 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003499 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
3500 /* The fields of a FILETIME structure are the hi and lo part
3501 of a 64-bit value expressed in 100 nanosecond units.
3502 1e7 is one second in such units; 1e-7 the inverse.
3503 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3504 */
Barry Warsaw53699e91996-12-10 23:23:01 +00003505 return Py_BuildValue(
3506 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00003507 (double)(kernel.dwHighDateTime*429.4967296 +
3508 kernel.dwLowDateTime*1e-7),
3509 (double)(user.dwHighDateTime*429.4967296 +
3510 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00003511 (double)0,
3512 (double)0,
3513 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00003514}
Guido van Rossum8d665e61996-06-26 18:22:49 +00003515#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003516
3517#ifdef HAVE_TIMES
Roger E. Masse0318fd61997-06-05 22:07:58 +00003518static char posix_times__doc__[] =
3519"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3520Return a tuple of floating point numbers indicating process times.";
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00003521#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003522
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003523
Guido van Rossumb6775db1994-08-01 11:34:53 +00003524#ifdef HAVE_SETSID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003525static char posix_setsid__doc__[] =
3526"setsid() -> None\n\
3527Call the system call setsid().";
3528
Barry Warsaw53699e91996-12-10 23:23:01 +00003529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003530posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003531{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003532 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003533 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003534 if (setsid() < 0)
3535 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003536 Py_INCREF(Py_None);
3537 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003538}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003539#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003540
Guido van Rossumb6775db1994-08-01 11:34:53 +00003541#ifdef HAVE_SETPGID
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003542static char posix_setpgid__doc__[] =
3543"setpgid(pid, pgrp) -> None\n\
3544Call the system call setpgid().";
3545
Barry Warsaw53699e91996-12-10 23:23:01 +00003546static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003547posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003548{
3549 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003550 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00003551 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003552 if (setpgid(pid, pgrp) < 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_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00003558
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003559
Guido van Rossumb6775db1994-08-01 11:34:53 +00003560#ifdef HAVE_TCGETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003561static char posix_tcgetpgrp__doc__[] =
3562"tcgetpgrp(fd) -> pgid\n\
3563Return the process group associated with the terminal given by a fd.";
3564
Barry Warsaw53699e91996-12-10 23:23:01 +00003565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003566posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003567{
3568 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003569 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003570 return NULL;
3571 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003572 if (pgid < 0)
3573 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003574 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00003575}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003576#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00003577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003578
Guido van Rossumb6775db1994-08-01 11:34:53 +00003579#ifdef HAVE_TCSETPGRP
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003580static char posix_tcsetpgrp__doc__[] =
3581"tcsetpgrp(fd, pgid) -> None\n\
3582Set the process group associated with the terminal given by a fd.";
3583
Barry Warsaw53699e91996-12-10 23:23:01 +00003584static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003585posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00003586{
3587 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003588 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00003589 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003590 if (tcsetpgrp(fd, pgid) < 0)
3591 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00003592 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00003593 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00003594}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003595#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00003596
Guido van Rossum687dd131993-05-17 08:34:16 +00003597/* Functions acting on file descriptors */
3598
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003599static char posix_open__doc__[] =
3600"open(filename, flag [, mode=0777]) -> fd\n\
3601Open a file (for low level IO).";
3602
Barry Warsaw53699e91996-12-10 23:23:01 +00003603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003604posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003605{
Mark Hammondef8b6542001-05-13 08:04:26 +00003606 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00003607 int flag;
3608 int mode = 0777;
3609 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00003610 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00003611 Py_FileSystemDefaultEncoding, &file,
3612 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00003613 return NULL;
3614
Barry Warsaw53699e91996-12-10 23:23:01 +00003615 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003616 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003617 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003618 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00003619 return posix_error_with_allocated_filename(file);
3620 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00003621 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003622}
3623
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003624
3625static char posix_close__doc__[] =
3626"close(fd) -> None\n\
3627Close a file descriptor (for low level IO).";
3628
Barry Warsaw53699e91996-12-10 23:23:01 +00003629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003630posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003631{
3632 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003633 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003634 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003635 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003636 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003637 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003638 if (res < 0)
3639 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003640 Py_INCREF(Py_None);
3641 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003642}
3643
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003644
3645static char posix_dup__doc__[] =
3646"dup(fd) -> fd2\n\
3647Return a duplicate of a file descriptor.";
3648
Barry Warsaw53699e91996-12-10 23:23:01 +00003649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003650posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003651{
3652 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003653 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003654 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003655 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003656 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00003657 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003658 if (fd < 0)
3659 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003660 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00003661}
3662
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003663
3664static char posix_dup2__doc__[] =
3665"dup2(fd, fd2) -> None\n\
3666Duplicate file descriptor.";
3667
Barry Warsaw53699e91996-12-10 23:23:01 +00003668static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003669posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003670{
3671 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003672 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00003673 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003674 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003675 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00003676 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003677 if (res < 0)
3678 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003679 Py_INCREF(Py_None);
3680 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00003681}
3682
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003683
3684static char posix_lseek__doc__[] =
3685"lseek(fd, pos, how) -> newpos\n\
3686Set the current position of a file descriptor.";
3687
Barry Warsaw53699e91996-12-10 23:23:01 +00003688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003689posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003690{
3691 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00003692#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003693 LONG_LONG pos, res;
3694#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00003695 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00003696#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00003697 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003698 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00003699 return NULL;
3700#ifdef SEEK_SET
3701 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3702 switch (how) {
3703 case 0: how = SEEK_SET; break;
3704 case 1: how = SEEK_CUR; break;
3705 case 2: how = SEEK_END; break;
3706 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003707#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00003708
3709#if !defined(HAVE_LARGEFILE_SUPPORT)
3710 pos = PyInt_AsLong(posobj);
3711#else
3712 pos = PyLong_Check(posobj) ?
3713 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3714#endif
3715 if (PyErr_Occurred())
3716 return NULL;
3717
Barry Warsaw53699e91996-12-10 23:23:01 +00003718 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00003719#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00003720 res = _lseeki64(fd, pos, how);
3721#else
Guido van Rossum687dd131993-05-17 08:34:16 +00003722 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00003723#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003724 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003725 if (res < 0)
3726 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00003727
3728#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00003729 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00003730#else
3731 return PyLong_FromLongLong(res);
3732#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003733}
3734
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003735
3736static char posix_read__doc__[] =
3737"read(fd, buffersize) -> string\n\
3738Read a file descriptor.";
3739
Barry Warsaw53699e91996-12-10 23:23:01 +00003740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003741posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003742{
Guido van Rossum8bac5461996-06-11 18:38:48 +00003743 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00003744 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003745 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003746 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003747 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003748 if (buffer == NULL)
3749 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003750 Py_BEGIN_ALLOW_THREADS
3751 n = read(fd, PyString_AsString(buffer), size);
3752 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00003753 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003754 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00003755 return posix_error();
3756 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00003757 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00003758 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00003759 return buffer;
3760}
3761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003762
3763static char posix_write__doc__[] =
3764"write(fd, string) -> byteswritten\n\
3765Write a string to a file descriptor.";
3766
Barry Warsaw53699e91996-12-10 23:23:01 +00003767static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003768posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003769{
3770 int fd, size;
3771 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003772 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00003773 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003774 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003775 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00003776 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003777 if (size < 0)
3778 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003779 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00003780}
3781
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003782
3783static char posix_fstat__doc__[]=
3784"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3785Like stat(), but for an open file descriptor.";
3786
Barry Warsaw53699e91996-12-10 23:23:01 +00003787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003788posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003789{
3790 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00003791 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00003792 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003793 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00003794 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003795 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003796 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00003797 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003798 if (res != 0)
3799 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00003800
Fred Drake699f3522000-06-29 21:12:41 +00003801 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00003802}
3803
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003804
3805static char posix_fdopen__doc__[] =
3806"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3807Return an open file object connected to a file descriptor.";
3808
Barry Warsaw53699e91996-12-10 23:23:01 +00003809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003810posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003811{
Guido van Rossum687dd131993-05-17 08:34:16 +00003812 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003813 char *mode = "r";
3814 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00003815 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003816 PyObject *f;
3817 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00003818 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00003819
Barry Warsaw53699e91996-12-10 23:23:01 +00003820 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003821 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003822 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003823 if (fp == NULL)
3824 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003825 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003826 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003827 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003828 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00003829}
3830
Skip Montanaro1517d842000-07-19 14:34:14 +00003831static char posix_isatty__doc__[] =
3832"isatty(fd) -> Boolean\n\
3833Return true if the file descriptor 'fd' is an open file descriptor\n\
Thomas Wouters12e15952000-10-03 16:54:24 +00003834connected to the slave end of a terminal.";
Skip Montanaro1517d842000-07-19 14:34:14 +00003835
3836static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00003837posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00003838{
3839 int fd;
3840 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3841 return NULL;
3842 return Py_BuildValue("i", isatty(fd));
3843}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003844
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003845#ifdef HAVE_PIPE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003846static char posix_pipe__doc__[] =
3847"pipe() -> (read_end, write_end)\n\
3848Create a pipe.";
3849
Barry Warsaw53699e91996-12-10 23:23:01 +00003850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003851posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00003852{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003853#if defined(PYOS_OS2)
3854 HFILE read, write;
3855 APIRET rc;
3856
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003857 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003858 return NULL;
3859
3860 Py_BEGIN_ALLOW_THREADS
3861 rc = DosCreatePipe( &read, &write, 4096);
3862 Py_END_ALLOW_THREADS
3863 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003864 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003865
3866 return Py_BuildValue("(ii)", read, write);
3867#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00003868#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00003869 int fds[2];
3870 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003871 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00003872 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003873 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003874 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00003875 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00003876 if (res != 0)
3877 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003878 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003879#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00003880 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003881 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00003882 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003883 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00003884 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003885 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003886 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00003887 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00003888 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003889 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00003890 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
3891 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00003892 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00003893#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003894#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00003895}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003896#endif /* HAVE_PIPE */
3897
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003898
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003899#ifdef HAVE_MKFIFO
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003900static char posix_mkfifo__doc__[] =
3901"mkfifo(file, [, mode=0666]) -> None\n\
3902Create a FIFO (a POSIX named pipe).";
3903
Barry Warsaw53699e91996-12-10 23:23:01 +00003904static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003905posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003906{
3907 char *file;
3908 int mode = 0666;
3909 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003910 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003911 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003912 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003913 res = mkfifo(file, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003914 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003915 if (res < 0)
3916 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003917 Py_INCREF(Py_None);
3918 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003919}
3920#endif
3921
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003922
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003923#ifdef HAVE_FTRUNCATE
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003924static char posix_ftruncate__doc__[] =
3925"ftruncate(fd, length) -> None\n\
3926Truncate a file to a specified length.";
3927
Barry Warsaw53699e91996-12-10 23:23:01 +00003928static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003929posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003930{
3931 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003932 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003933 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00003934 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003935
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003936 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00003937 return NULL;
3938
3939#if !defined(HAVE_LARGEFILE_SUPPORT)
3940 length = PyInt_AsLong(lenobj);
3941#else
3942 length = PyLong_Check(lenobj) ?
3943 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3944#endif
3945 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003946 return NULL;
3947
Barry Warsaw53699e91996-12-10 23:23:01 +00003948 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003949 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00003950 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003951 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00003952 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003953 return NULL;
3954 }
Barry Warsaw53699e91996-12-10 23:23:01 +00003955 Py_INCREF(Py_None);
3956 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003957}
3958#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00003959
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003960#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003961static char posix_putenv__doc__[] =
3962"putenv(key, value) -> None\n\
3963Change or add an environment variable.";
3964
Fred Drake762e2061999-08-26 17:23:54 +00003965/* Save putenv() parameters as values here, so we can collect them when they
3966 * get re-set with another call for the same key. */
3967static PyObject *posix_putenv_garbage;
3968
Tim Peters5aa91602002-01-30 05:46:57 +00003969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003970posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003971{
3972 char *s1, *s2;
3973 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00003974 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00003975 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003976
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003977 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00003978 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00003979
3980#if defined(PYOS_OS2)
3981 if (stricmp(s1, "BEGINLIBPATH") == 0) {
3982 APIRET rc;
3983
3984 if (strlen(s2) == 0) /* If New Value is an Empty String */
3985 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3986
3987 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3988 if (rc != NO_ERROR)
3989 return os2_error(rc);
3990
3991 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3992 APIRET rc;
3993
3994 if (strlen(s2) == 0) /* If New Value is an Empty String */
3995 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
3996
3997 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3998 if (rc != NO_ERROR)
3999 return os2_error(rc);
4000 } else {
4001#endif
4002
Fred Drake762e2061999-08-26 17:23:54 +00004003 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004004 len = strlen(s1) + strlen(s2) + 2;
4005 /* len includes space for a trailing \0; the size arg to
4006 PyString_FromStringAndSize does not count that */
4007 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004008 if (newstr == NULL)
4009 return PyErr_NoMemory();
4010 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004011 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004012 if (putenv(new)) {
4013 posix_error();
4014 return NULL;
4015 }
Fred Drake762e2061999-08-26 17:23:54 +00004016 /* Install the first arg and newstr in posix_putenv_garbage;
4017 * this will cause previous value to be collected. This has to
4018 * happen after the real putenv() call because the old value
4019 * was still accessible until then. */
4020 if (PyDict_SetItem(posix_putenv_garbage,
4021 PyTuple_GET_ITEM(args, 0), newstr)) {
4022 /* really not much we can do; just leak */
4023 PyErr_Clear();
4024 }
4025 else {
4026 Py_DECREF(newstr);
4027 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004028
4029#if defined(PYOS_OS2)
4030 }
4031#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004032 Py_INCREF(Py_None);
4033 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004034}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004035#endif /* putenv */
4036
Guido van Rossumc524d952001-10-19 01:31:59 +00004037#ifdef HAVE_UNSETENV
4038static char posix_unsetenv__doc__[] =
4039"unsetenv(key) -> None\n\
4040Delete an environment variable.";
4041
4042static PyObject *
4043posix_unsetenv(PyObject *self, PyObject *args)
4044{
4045 char *s1;
4046
4047 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4048 return NULL;
4049
4050 unsetenv(s1);
4051
4052 /* Remove the key from posix_putenv_garbage;
4053 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004054 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004055 * old value was still accessible until then.
4056 */
4057 if (PyDict_DelItem(posix_putenv_garbage,
4058 PyTuple_GET_ITEM(args, 0))) {
4059 /* really not much we can do; just leak */
4060 PyErr_Clear();
4061 }
4062
4063 Py_INCREF(Py_None);
4064 return Py_None;
4065}
4066#endif /* unsetenv */
4067
Guido van Rossumb6a47161997-09-15 22:54:34 +00004068#ifdef HAVE_STRERROR
4069static char posix_strerror__doc__[] =
4070"strerror(code) -> string\n\
4071Translate an error code to a message string.";
4072
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004074posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004075{
4076 int code;
4077 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004078 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004079 return NULL;
4080 message = strerror(code);
4081 if (message == NULL) {
4082 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004083 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004084 return NULL;
4085 }
4086 return PyString_FromString(message);
4087}
4088#endif /* strerror */
4089
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004090
Guido van Rossumc9641791998-08-04 15:26:23 +00004091#ifdef HAVE_SYS_WAIT_H
4092
4093#ifdef WIFSTOPPED
4094static char posix_WIFSTOPPED__doc__[] =
4095"WIFSTOPPED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004096Return true if the process returning 'status' was stopped.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004097
4098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004099posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004100{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004101#ifdef UNION_WAIT
4102 union wait status;
4103#define status_i (status.w_status)
4104#else
4105 int status;
4106#define status_i status
4107#endif
4108 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004109
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004110 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004111 {
4112 return NULL;
4113 }
Tim Peters5aa91602002-01-30 05:46:57 +00004114
Guido van Rossumc9641791998-08-04 15:26:23 +00004115 return Py_BuildValue("i", WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004116#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004117}
4118#endif /* WIFSTOPPED */
4119
4120#ifdef WIFSIGNALED
4121static char posix_WIFSIGNALED__doc__[] =
4122"WIFSIGNALED(status) -> Boolean\n\
Guido van Rossum3366d1c1999-02-23 18:34:43 +00004123Return true if the process returning 'status' was terminated by a signal.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004124
4125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004126posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004127{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004128#ifdef UNION_WAIT
4129 union wait status;
4130#define status_i (status.w_status)
4131#else
4132 int status;
4133#define status_i status
4134#endif
4135 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004136
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004137 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004138 {
4139 return NULL;
4140 }
Tim Peters5aa91602002-01-30 05:46:57 +00004141
Guido van Rossumc9641791998-08-04 15:26:23 +00004142 return Py_BuildValue("i", WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004143#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004144}
4145#endif /* WIFSIGNALED */
4146
4147#ifdef WIFEXITED
4148static char posix_WIFEXITED__doc__[] =
4149"WIFEXITED(status) -> Boolean\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004150Return true if the process returning 'status' exited using the exit()\n\
4151system call.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004152
4153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004154posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004155{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004156#ifdef UNION_WAIT
4157 union wait status;
4158#define status_i (status.w_status)
4159#else
4160 int status;
4161#define status_i status
4162#endif
4163 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004164
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004165 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004166 {
4167 return NULL;
4168 }
Tim Peters5aa91602002-01-30 05:46:57 +00004169
Guido van Rossumc9641791998-08-04 15:26:23 +00004170 return Py_BuildValue("i", WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004171#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004172}
4173#endif /* WIFEXITED */
4174
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004175#ifdef WEXITSTATUS
Guido van Rossumc9641791998-08-04 15:26:23 +00004176static char posix_WEXITSTATUS__doc__[] =
4177"WEXITSTATUS(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004178Return the process return code from 'status'.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004179
4180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004181posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004182{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004183#ifdef UNION_WAIT
4184 union wait status;
4185#define status_i (status.w_status)
4186#else
4187 int status;
4188#define status_i status
4189#endif
4190 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004191
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004192 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004193 {
4194 return NULL;
4195 }
Tim Peters5aa91602002-01-30 05:46:57 +00004196
Guido van Rossumc9641791998-08-04 15:26:23 +00004197 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004198#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004199}
4200#endif /* WEXITSTATUS */
4201
4202#ifdef WTERMSIG
4203static char posix_WTERMSIG__doc__[] =
4204"WTERMSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004205Return the signal that terminated the process that provided the 'status'\n\
4206value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004207
4208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004209posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004210{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004211#ifdef UNION_WAIT
4212 union wait status;
4213#define status_i (status.w_status)
4214#else
4215 int status;
4216#define status_i status
4217#endif
4218 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004219
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004220 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004221 {
4222 return NULL;
4223 }
Tim Peters5aa91602002-01-30 05:46:57 +00004224
Guido van Rossumc9641791998-08-04 15:26:23 +00004225 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004226#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004227}
4228#endif /* WTERMSIG */
4229
4230#ifdef WSTOPSIG
4231static char posix_WSTOPSIG__doc__[] =
4232"WSTOPSIG(status) -> integer\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004233Return the signal that stopped the process that provided the 'status' value.";
Guido van Rossumc9641791998-08-04 15:26:23 +00004234
4235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004236posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004237{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004238#ifdef UNION_WAIT
4239 union wait status;
4240#define status_i (status.w_status)
4241#else
4242 int status;
4243#define status_i status
4244#endif
4245 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004246
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004247 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004248 {
4249 return NULL;
4250 }
Tim Peters5aa91602002-01-30 05:46:57 +00004251
Guido van Rossumc9641791998-08-04 15:26:23 +00004252 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004253#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004254}
4255#endif /* WSTOPSIG */
4256
4257#endif /* HAVE_SYS_WAIT_H */
4258
4259
Guido van Rossum94f6f721999-01-06 18:42:14 +00004260#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00004261#ifdef _SCO_DS
4262/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4263 needed definitions in sys/statvfs.h */
4264#define _SVID3
4265#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004266#include <sys/statvfs.h>
4267
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004268static PyObject*
4269_pystatvfs_fromstructstatvfs(struct statvfs st) {
4270 PyObject *v = PyStructSequence_New(&StatVFSResultType);
4271 if (v == NULL)
4272 return NULL;
4273
4274#if !defined(HAVE_LARGEFILE_SUPPORT)
4275 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4276 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
4277 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
4278 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
4279 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
4280 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
4281 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
4282 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
4283 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4284 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4285#else
4286 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
4287 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00004288 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004289 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00004290 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004291 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
4292 PyStructSequence_SET_ITEM(v, 4,
4293 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00004294 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004295 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00004296 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004297 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00004298 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004299 PyLong_FromLongLong((LONG_LONG) st.f_favail));
4300 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
4301 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
4302#endif
4303
4304 return v;
4305}
4306
Guido van Rossum94f6f721999-01-06 18:42:14 +00004307static char posix_fstatvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004308"fstatvfs(fd) -> \n\
4309 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004310Perform an fstatvfs system call on the given fd.";
4311
4312static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004313posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004314{
4315 int fd, res;
4316 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004317
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004318 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004319 return NULL;
4320 Py_BEGIN_ALLOW_THREADS
4321 res = fstatvfs(fd, &st);
4322 Py_END_ALLOW_THREADS
4323 if (res != 0)
4324 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004325
4326 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004327}
4328#endif /* HAVE_FSTATVFS */
4329
4330
4331#if defined(HAVE_STATVFS)
4332#include <sys/statvfs.h>
4333
4334static char posix_statvfs__doc__[] =
Guido van Rossum0c9608c1999-02-03 16:32:37 +00004335"statvfs(path) -> \n\
4336 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
Guido van Rossum94f6f721999-01-06 18:42:14 +00004337Perform a statvfs system call on the given path.";
4338
4339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004340posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00004341{
4342 char *path;
4343 int res;
4344 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004345 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004346 return NULL;
4347 Py_BEGIN_ALLOW_THREADS
4348 res = statvfs(path, &st);
4349 Py_END_ALLOW_THREADS
4350 if (res != 0)
4351 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00004352
4353 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004354}
4355#endif /* HAVE_STATVFS */
4356
4357
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004358#ifdef HAVE_TEMPNAM
4359static char posix_tempnam__doc__[] = "\
4360tempnam([dir[, prefix]]) -> string\n\
4361Return a unique name for a temporary file.\n\
4362The directory and a short may be specified as strings; they may be omitted\n\
4363or None if not needed.";
4364
4365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004366posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004367{
4368 PyObject *result = NULL;
4369 char *dir = NULL;
4370 char *pfx = NULL;
4371 char *name;
4372
4373 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
4374 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004375
4376 if (PyErr_Warn(PyExc_RuntimeWarning,
4377 "tempnam is a potential security risk to your program") < 0)
4378 return NULL;
4379
Fred Drake78b71c22001-07-17 20:37:36 +00004380#ifdef MS_WIN32
4381 name = _tempnam(dir, pfx);
4382#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004383 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00004384#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004385 if (name == NULL)
4386 return PyErr_NoMemory();
4387 result = PyString_FromString(name);
4388 free(name);
4389 return result;
4390}
Guido van Rossumd371ff11999-01-25 16:12:23 +00004391#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004392
4393
4394#ifdef HAVE_TMPFILE
4395static char posix_tmpfile__doc__[] = "\
4396tmpfile() -> file object\n\
4397Create a temporary file with no directory entries.";
4398
4399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004400posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004401{
4402 FILE *fp;
4403
4404 if (!PyArg_ParseTuple(args, ":tmpfile"))
4405 return NULL;
4406 fp = tmpfile();
4407 if (fp == NULL)
4408 return posix_error();
4409 return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
4410}
4411#endif
4412
4413
4414#ifdef HAVE_TMPNAM
4415static char posix_tmpnam__doc__[] = "\
4416tmpnam() -> string\n\
4417Return a unique name for a temporary file.";
4418
4419static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004420posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004421{
4422 char buffer[L_tmpnam];
4423 char *name;
4424
4425 if (!PyArg_ParseTuple(args, ":tmpnam"))
4426 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00004427
4428 if (PyErr_Warn(PyExc_RuntimeWarning,
4429 "tmpnam is a potential security risk to your program") < 0)
4430 return NULL;
4431
Greg Wardb48bc172000-03-01 21:51:56 +00004432#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004433 name = tmpnam_r(buffer);
4434#else
4435 name = tmpnam(buffer);
4436#endif
4437 if (name == NULL) {
4438 PyErr_SetObject(PyExc_OSError,
4439 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00004440#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004441 "unexpected NULL from tmpnam_r"
4442#else
4443 "unexpected NULL from tmpnam"
4444#endif
4445 ));
4446 return NULL;
4447 }
4448 return PyString_FromString(buffer);
4449}
4450#endif
4451
4452
Fred Drakec9680921999-12-13 16:37:25 +00004453/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4454 * It maps strings representing configuration variable names to
4455 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00004456 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00004457 * rarely-used constants. There are three separate tables that use
4458 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00004459 *
4460 * This code is always included, even if none of the interfaces that
4461 * need it are included. The #if hackery needed to avoid it would be
4462 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00004463 */
4464struct constdef {
4465 char *name;
4466 long value;
4467};
4468
Fred Drake12c6e2d1999-12-14 21:25:03 +00004469static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004470conv_confname(PyObject *arg, int *valuep, struct constdef *table,
4471 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00004472{
4473 if (PyInt_Check(arg)) {
4474 *valuep = PyInt_AS_LONG(arg);
4475 return 1;
4476 }
4477 if (PyString_Check(arg)) {
4478 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00004479 size_t lo = 0;
4480 size_t mid;
4481 size_t hi = tablesize;
4482 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00004483 char *confname = PyString_AS_STRING(arg);
4484 while (lo < hi) {
4485 mid = (lo + hi) / 2;
4486 cmp = strcmp(confname, table[mid].name);
4487 if (cmp < 0)
4488 hi = mid;
4489 else if (cmp > 0)
4490 lo = mid + 1;
4491 else {
4492 *valuep = table[mid].value;
4493 return 1;
4494 }
4495 }
4496 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
4497 }
4498 else
4499 PyErr_SetString(PyExc_TypeError,
4500 "configuration names must be strings or integers");
4501 return 0;
4502}
4503
4504
4505#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4506static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004507#ifdef _PC_ABI_AIO_XFER_MAX
4508 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
4509#endif
4510#ifdef _PC_ABI_ASYNC_IO
4511 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
4512#endif
Fred Drakec9680921999-12-13 16:37:25 +00004513#ifdef _PC_ASYNC_IO
4514 {"PC_ASYNC_IO", _PC_ASYNC_IO},
4515#endif
4516#ifdef _PC_CHOWN_RESTRICTED
4517 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
4518#endif
4519#ifdef _PC_FILESIZEBITS
4520 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
4521#endif
4522#ifdef _PC_LAST
4523 {"PC_LAST", _PC_LAST},
4524#endif
4525#ifdef _PC_LINK_MAX
4526 {"PC_LINK_MAX", _PC_LINK_MAX},
4527#endif
4528#ifdef _PC_MAX_CANON
4529 {"PC_MAX_CANON", _PC_MAX_CANON},
4530#endif
4531#ifdef _PC_MAX_INPUT
4532 {"PC_MAX_INPUT", _PC_MAX_INPUT},
4533#endif
4534#ifdef _PC_NAME_MAX
4535 {"PC_NAME_MAX", _PC_NAME_MAX},
4536#endif
4537#ifdef _PC_NO_TRUNC
4538 {"PC_NO_TRUNC", _PC_NO_TRUNC},
4539#endif
4540#ifdef _PC_PATH_MAX
4541 {"PC_PATH_MAX", _PC_PATH_MAX},
4542#endif
4543#ifdef _PC_PIPE_BUF
4544 {"PC_PIPE_BUF", _PC_PIPE_BUF},
4545#endif
4546#ifdef _PC_PRIO_IO
4547 {"PC_PRIO_IO", _PC_PRIO_IO},
4548#endif
4549#ifdef _PC_SOCK_MAXBUF
4550 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
4551#endif
4552#ifdef _PC_SYNC_IO
4553 {"PC_SYNC_IO", _PC_SYNC_IO},
4554#endif
4555#ifdef _PC_VDISABLE
4556 {"PC_VDISABLE", _PC_VDISABLE},
4557#endif
4558};
4559
Fred Drakec9680921999-12-13 16:37:25 +00004560static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004561conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004562{
4563 return conv_confname(arg, valuep, posix_constants_pathconf,
4564 sizeof(posix_constants_pathconf)
4565 / sizeof(struct constdef));
4566}
4567#endif
4568
4569#ifdef HAVE_FPATHCONF
4570static char posix_fpathconf__doc__[] = "\
4571fpathconf(fd, name) -> integer\n\
4572Return the configuration limit name for the file descriptor fd.\n\
4573If there is no limit, return -1.";
4574
4575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004576posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004577{
4578 PyObject *result = NULL;
4579 int name, fd;
4580
Fred Drake12c6e2d1999-12-14 21:25:03 +00004581 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4582 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00004583 long limit;
4584
4585 errno = 0;
4586 limit = fpathconf(fd, name);
4587 if (limit == -1 && errno != 0)
4588 posix_error();
4589 else
4590 result = PyInt_FromLong(limit);
4591 }
4592 return result;
4593}
4594#endif
4595
4596
4597#ifdef HAVE_PATHCONF
4598static char posix_pathconf__doc__[] = "\
4599pathconf(path, name) -> integer\n\
4600Return the configuration limit name for the file or directory path.\n\
4601If there is no limit, return -1.";
4602
4603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004604posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004605{
4606 PyObject *result = NULL;
4607 int name;
4608 char *path;
4609
4610 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4611 conv_path_confname, &name)) {
4612 long limit;
4613
4614 errno = 0;
4615 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004616 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00004617 if (errno == EINVAL)
4618 /* could be a path or name problem */
4619 posix_error();
4620 else
4621 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00004622 }
Fred Drakec9680921999-12-13 16:37:25 +00004623 else
4624 result = PyInt_FromLong(limit);
4625 }
4626 return result;
4627}
4628#endif
4629
4630#ifdef HAVE_CONFSTR
4631static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00004632#ifdef _CS_ARCHITECTURE
4633 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
4634#endif
4635#ifdef _CS_HOSTNAME
4636 {"CS_HOSTNAME", _CS_HOSTNAME},
4637#endif
4638#ifdef _CS_HW_PROVIDER
4639 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
4640#endif
4641#ifdef _CS_HW_SERIAL
4642 {"CS_HW_SERIAL", _CS_HW_SERIAL},
4643#endif
4644#ifdef _CS_INITTAB_NAME
4645 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
4646#endif
Fred Drakec9680921999-12-13 16:37:25 +00004647#ifdef _CS_LFS64_CFLAGS
4648 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
4649#endif
4650#ifdef _CS_LFS64_LDFLAGS
4651 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
4652#endif
4653#ifdef _CS_LFS64_LIBS
4654 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
4655#endif
4656#ifdef _CS_LFS64_LINTFLAGS
4657 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
4658#endif
4659#ifdef _CS_LFS_CFLAGS
4660 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
4661#endif
4662#ifdef _CS_LFS_LDFLAGS
4663 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
4664#endif
4665#ifdef _CS_LFS_LIBS
4666 {"CS_LFS_LIBS", _CS_LFS_LIBS},
4667#endif
4668#ifdef _CS_LFS_LINTFLAGS
4669 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
4670#endif
Fred Draked86ed291999-12-15 15:34:33 +00004671#ifdef _CS_MACHINE
4672 {"CS_MACHINE", _CS_MACHINE},
4673#endif
Fred Drakec9680921999-12-13 16:37:25 +00004674#ifdef _CS_PATH
4675 {"CS_PATH", _CS_PATH},
4676#endif
Fred Draked86ed291999-12-15 15:34:33 +00004677#ifdef _CS_RELEASE
4678 {"CS_RELEASE", _CS_RELEASE},
4679#endif
4680#ifdef _CS_SRPC_DOMAIN
4681 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
4682#endif
4683#ifdef _CS_SYSNAME
4684 {"CS_SYSNAME", _CS_SYSNAME},
4685#endif
4686#ifdef _CS_VERSION
4687 {"CS_VERSION", _CS_VERSION},
4688#endif
Fred Drakec9680921999-12-13 16:37:25 +00004689#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4690 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
4691#endif
4692#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4693 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
4694#endif
4695#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4696 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
4697#endif
4698#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4699 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
4700#endif
4701#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4702 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
4703#endif
4704#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4705 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4706#endif
4707#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4708 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
4709#endif
4710#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4711 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4712#endif
4713#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4714 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
4715#endif
4716#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4717 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
4718#endif
4719#ifdef _CS_XBS5_LP64_OFF64_LIBS
4720 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
4721#endif
4722#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4723 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
4724#endif
4725#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4726 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4727#endif
4728#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4729 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4730#endif
4731#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4732 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
4733#endif
4734#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4735 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4736#endif
Fred Draked86ed291999-12-15 15:34:33 +00004737#ifdef _MIPS_CS_AVAIL_PROCESSORS
4738 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
4739#endif
4740#ifdef _MIPS_CS_BASE
4741 {"MIPS_CS_BASE", _MIPS_CS_BASE},
4742#endif
4743#ifdef _MIPS_CS_HOSTID
4744 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
4745#endif
4746#ifdef _MIPS_CS_HW_NAME
4747 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
4748#endif
4749#ifdef _MIPS_CS_NUM_PROCESSORS
4750 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
4751#endif
4752#ifdef _MIPS_CS_OSREL_MAJ
4753 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
4754#endif
4755#ifdef _MIPS_CS_OSREL_MIN
4756 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
4757#endif
4758#ifdef _MIPS_CS_OSREL_PATCH
4759 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
4760#endif
4761#ifdef _MIPS_CS_OS_NAME
4762 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
4763#endif
4764#ifdef _MIPS_CS_OS_PROVIDER
4765 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
4766#endif
4767#ifdef _MIPS_CS_PROCESSORS
4768 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
4769#endif
4770#ifdef _MIPS_CS_SERIAL
4771 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
4772#endif
4773#ifdef _MIPS_CS_VENDOR
4774 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
4775#endif
Fred Drakec9680921999-12-13 16:37:25 +00004776};
4777
4778static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004779conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00004780{
4781 return conv_confname(arg, valuep, posix_constants_confstr,
4782 sizeof(posix_constants_confstr)
4783 / sizeof(struct constdef));
4784}
4785
4786static char posix_confstr__doc__[] = "\
4787confstr(name) -> string\n\
4788Return a string-valued system configuration variable.";
4789
4790static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004791posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00004792{
4793 PyObject *result = NULL;
4794 int name;
4795 char buffer[64];
4796
4797 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4798 int len = confstr(name, buffer, sizeof(buffer));
4799
Fred Drakec9680921999-12-13 16:37:25 +00004800 errno = 0;
4801 if (len == 0) {
4802 if (errno != 0)
4803 posix_error();
4804 else
4805 result = PyString_FromString("");
4806 }
4807 else {
4808 if (len >= sizeof(buffer)) {
4809 result = PyString_FromStringAndSize(NULL, len);
4810 if (result != NULL)
4811 confstr(name, PyString_AS_STRING(result), len+1);
4812 }
4813 else
4814 result = PyString_FromString(buffer);
4815 }
4816 }
4817 return result;
4818}
4819#endif
4820
4821
4822#ifdef HAVE_SYSCONF
4823static struct constdef posix_constants_sysconf[] = {
4824#ifdef _SC_2_CHAR_TERM
4825 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
4826#endif
4827#ifdef _SC_2_C_BIND
4828 {"SC_2_C_BIND", _SC_2_C_BIND},
4829#endif
4830#ifdef _SC_2_C_DEV
4831 {"SC_2_C_DEV", _SC_2_C_DEV},
4832#endif
4833#ifdef _SC_2_C_VERSION
4834 {"SC_2_C_VERSION", _SC_2_C_VERSION},
4835#endif
4836#ifdef _SC_2_FORT_DEV
4837 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
4838#endif
4839#ifdef _SC_2_FORT_RUN
4840 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
4841#endif
4842#ifdef _SC_2_LOCALEDEF
4843 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
4844#endif
4845#ifdef _SC_2_SW_DEV
4846 {"SC_2_SW_DEV", _SC_2_SW_DEV},
4847#endif
4848#ifdef _SC_2_UPE
4849 {"SC_2_UPE", _SC_2_UPE},
4850#endif
4851#ifdef _SC_2_VERSION
4852 {"SC_2_VERSION", _SC_2_VERSION},
4853#endif
Fred Draked86ed291999-12-15 15:34:33 +00004854#ifdef _SC_ABI_ASYNCHRONOUS_IO
4855 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
4856#endif
4857#ifdef _SC_ACL
4858 {"SC_ACL", _SC_ACL},
4859#endif
Fred Drakec9680921999-12-13 16:37:25 +00004860#ifdef _SC_AIO_LISTIO_MAX
4861 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
4862#endif
Fred Drakec9680921999-12-13 16:37:25 +00004863#ifdef _SC_AIO_MAX
4864 {"SC_AIO_MAX", _SC_AIO_MAX},
4865#endif
4866#ifdef _SC_AIO_PRIO_DELTA_MAX
4867 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
4868#endif
4869#ifdef _SC_ARG_MAX
4870 {"SC_ARG_MAX", _SC_ARG_MAX},
4871#endif
4872#ifdef _SC_ASYNCHRONOUS_IO
4873 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
4874#endif
4875#ifdef _SC_ATEXIT_MAX
4876 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
4877#endif
Fred Draked86ed291999-12-15 15:34:33 +00004878#ifdef _SC_AUDIT
4879 {"SC_AUDIT", _SC_AUDIT},
4880#endif
Fred Drakec9680921999-12-13 16:37:25 +00004881#ifdef _SC_AVPHYS_PAGES
4882 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
4883#endif
4884#ifdef _SC_BC_BASE_MAX
4885 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
4886#endif
4887#ifdef _SC_BC_DIM_MAX
4888 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
4889#endif
4890#ifdef _SC_BC_SCALE_MAX
4891 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
4892#endif
4893#ifdef _SC_BC_STRING_MAX
4894 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
4895#endif
Fred Draked86ed291999-12-15 15:34:33 +00004896#ifdef _SC_CAP
4897 {"SC_CAP", _SC_CAP},
4898#endif
Fred Drakec9680921999-12-13 16:37:25 +00004899#ifdef _SC_CHARCLASS_NAME_MAX
4900 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
4901#endif
4902#ifdef _SC_CHAR_BIT
4903 {"SC_CHAR_BIT", _SC_CHAR_BIT},
4904#endif
4905#ifdef _SC_CHAR_MAX
4906 {"SC_CHAR_MAX", _SC_CHAR_MAX},
4907#endif
4908#ifdef _SC_CHAR_MIN
4909 {"SC_CHAR_MIN", _SC_CHAR_MIN},
4910#endif
4911#ifdef _SC_CHILD_MAX
4912 {"SC_CHILD_MAX", _SC_CHILD_MAX},
4913#endif
4914#ifdef _SC_CLK_TCK
4915 {"SC_CLK_TCK", _SC_CLK_TCK},
4916#endif
4917#ifdef _SC_COHER_BLKSZ
4918 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
4919#endif
4920#ifdef _SC_COLL_WEIGHTS_MAX
4921 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
4922#endif
4923#ifdef _SC_DCACHE_ASSOC
4924 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
4925#endif
4926#ifdef _SC_DCACHE_BLKSZ
4927 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
4928#endif
4929#ifdef _SC_DCACHE_LINESZ
4930 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
4931#endif
4932#ifdef _SC_DCACHE_SZ
4933 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
4934#endif
4935#ifdef _SC_DCACHE_TBLKSZ
4936 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
4937#endif
4938#ifdef _SC_DELAYTIMER_MAX
4939 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
4940#endif
4941#ifdef _SC_EQUIV_CLASS_MAX
4942 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
4943#endif
4944#ifdef _SC_EXPR_NEST_MAX
4945 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
4946#endif
4947#ifdef _SC_FSYNC
4948 {"SC_FSYNC", _SC_FSYNC},
4949#endif
4950#ifdef _SC_GETGR_R_SIZE_MAX
4951 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
4952#endif
4953#ifdef _SC_GETPW_R_SIZE_MAX
4954 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
4955#endif
4956#ifdef _SC_ICACHE_ASSOC
4957 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
4958#endif
4959#ifdef _SC_ICACHE_BLKSZ
4960 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
4961#endif
4962#ifdef _SC_ICACHE_LINESZ
4963 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
4964#endif
4965#ifdef _SC_ICACHE_SZ
4966 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
4967#endif
Fred Draked86ed291999-12-15 15:34:33 +00004968#ifdef _SC_INF
4969 {"SC_INF", _SC_INF},
4970#endif
Fred Drakec9680921999-12-13 16:37:25 +00004971#ifdef _SC_INT_MAX
4972 {"SC_INT_MAX", _SC_INT_MAX},
4973#endif
4974#ifdef _SC_INT_MIN
4975 {"SC_INT_MIN", _SC_INT_MIN},
4976#endif
4977#ifdef _SC_IOV_MAX
4978 {"SC_IOV_MAX", _SC_IOV_MAX},
4979#endif
Fred Draked86ed291999-12-15 15:34:33 +00004980#ifdef _SC_IP_SECOPTS
4981 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
4982#endif
Fred Drakec9680921999-12-13 16:37:25 +00004983#ifdef _SC_JOB_CONTROL
4984 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
4985#endif
Fred Draked86ed291999-12-15 15:34:33 +00004986#ifdef _SC_KERN_POINTERS
4987 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
4988#endif
4989#ifdef _SC_KERN_SIM
4990 {"SC_KERN_SIM", _SC_KERN_SIM},
4991#endif
Fred Drakec9680921999-12-13 16:37:25 +00004992#ifdef _SC_LINE_MAX
4993 {"SC_LINE_MAX", _SC_LINE_MAX},
4994#endif
4995#ifdef _SC_LOGIN_NAME_MAX
4996 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
4997#endif
4998#ifdef _SC_LOGNAME_MAX
4999 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5000#endif
5001#ifdef _SC_LONG_BIT
5002 {"SC_LONG_BIT", _SC_LONG_BIT},
5003#endif
Fred Draked86ed291999-12-15 15:34:33 +00005004#ifdef _SC_MAC
5005 {"SC_MAC", _SC_MAC},
5006#endif
Fred Drakec9680921999-12-13 16:37:25 +00005007#ifdef _SC_MAPPED_FILES
5008 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5009#endif
5010#ifdef _SC_MAXPID
5011 {"SC_MAXPID", _SC_MAXPID},
5012#endif
5013#ifdef _SC_MB_LEN_MAX
5014 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5015#endif
5016#ifdef _SC_MEMLOCK
5017 {"SC_MEMLOCK", _SC_MEMLOCK},
5018#endif
5019#ifdef _SC_MEMLOCK_RANGE
5020 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5021#endif
5022#ifdef _SC_MEMORY_PROTECTION
5023 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5024#endif
5025#ifdef _SC_MESSAGE_PASSING
5026 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5027#endif
Fred Draked86ed291999-12-15 15:34:33 +00005028#ifdef _SC_MMAP_FIXED_ALIGNMENT
5029 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5030#endif
Fred Drakec9680921999-12-13 16:37:25 +00005031#ifdef _SC_MQ_OPEN_MAX
5032 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5033#endif
5034#ifdef _SC_MQ_PRIO_MAX
5035 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5036#endif
Fred Draked86ed291999-12-15 15:34:33 +00005037#ifdef _SC_NACLS_MAX
5038 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5039#endif
Fred Drakec9680921999-12-13 16:37:25 +00005040#ifdef _SC_NGROUPS_MAX
5041 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5042#endif
5043#ifdef _SC_NL_ARGMAX
5044 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5045#endif
5046#ifdef _SC_NL_LANGMAX
5047 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5048#endif
5049#ifdef _SC_NL_MSGMAX
5050 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5051#endif
5052#ifdef _SC_NL_NMAX
5053 {"SC_NL_NMAX", _SC_NL_NMAX},
5054#endif
5055#ifdef _SC_NL_SETMAX
5056 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5057#endif
5058#ifdef _SC_NL_TEXTMAX
5059 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5060#endif
5061#ifdef _SC_NPROCESSORS_CONF
5062 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5063#endif
5064#ifdef _SC_NPROCESSORS_ONLN
5065 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5066#endif
Fred Draked86ed291999-12-15 15:34:33 +00005067#ifdef _SC_NPROC_CONF
5068 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5069#endif
5070#ifdef _SC_NPROC_ONLN
5071 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5072#endif
Fred Drakec9680921999-12-13 16:37:25 +00005073#ifdef _SC_NZERO
5074 {"SC_NZERO", _SC_NZERO},
5075#endif
5076#ifdef _SC_OPEN_MAX
5077 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5078#endif
5079#ifdef _SC_PAGESIZE
5080 {"SC_PAGESIZE", _SC_PAGESIZE},
5081#endif
5082#ifdef _SC_PAGE_SIZE
5083 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5084#endif
5085#ifdef _SC_PASS_MAX
5086 {"SC_PASS_MAX", _SC_PASS_MAX},
5087#endif
5088#ifdef _SC_PHYS_PAGES
5089 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5090#endif
5091#ifdef _SC_PII
5092 {"SC_PII", _SC_PII},
5093#endif
5094#ifdef _SC_PII_INTERNET
5095 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5096#endif
5097#ifdef _SC_PII_INTERNET_DGRAM
5098 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5099#endif
5100#ifdef _SC_PII_INTERNET_STREAM
5101 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5102#endif
5103#ifdef _SC_PII_OSI
5104 {"SC_PII_OSI", _SC_PII_OSI},
5105#endif
5106#ifdef _SC_PII_OSI_CLTS
5107 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5108#endif
5109#ifdef _SC_PII_OSI_COTS
5110 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5111#endif
5112#ifdef _SC_PII_OSI_M
5113 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5114#endif
5115#ifdef _SC_PII_SOCKET
5116 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5117#endif
5118#ifdef _SC_PII_XTI
5119 {"SC_PII_XTI", _SC_PII_XTI},
5120#endif
5121#ifdef _SC_POLL
5122 {"SC_POLL", _SC_POLL},
5123#endif
5124#ifdef _SC_PRIORITIZED_IO
5125 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5126#endif
5127#ifdef _SC_PRIORITY_SCHEDULING
5128 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5129#endif
5130#ifdef _SC_REALTIME_SIGNALS
5131 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5132#endif
5133#ifdef _SC_RE_DUP_MAX
5134 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5135#endif
5136#ifdef _SC_RTSIG_MAX
5137 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5138#endif
5139#ifdef _SC_SAVED_IDS
5140 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5141#endif
5142#ifdef _SC_SCHAR_MAX
5143 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5144#endif
5145#ifdef _SC_SCHAR_MIN
5146 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5147#endif
5148#ifdef _SC_SELECT
5149 {"SC_SELECT", _SC_SELECT},
5150#endif
5151#ifdef _SC_SEMAPHORES
5152 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5153#endif
5154#ifdef _SC_SEM_NSEMS_MAX
5155 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5156#endif
5157#ifdef _SC_SEM_VALUE_MAX
5158 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5159#endif
5160#ifdef _SC_SHARED_MEMORY_OBJECTS
5161 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5162#endif
5163#ifdef _SC_SHRT_MAX
5164 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5165#endif
5166#ifdef _SC_SHRT_MIN
5167 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5168#endif
5169#ifdef _SC_SIGQUEUE_MAX
5170 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5171#endif
5172#ifdef _SC_SIGRT_MAX
5173 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5174#endif
5175#ifdef _SC_SIGRT_MIN
5176 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5177#endif
Fred Draked86ed291999-12-15 15:34:33 +00005178#ifdef _SC_SOFTPOWER
5179 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5180#endif
Fred Drakec9680921999-12-13 16:37:25 +00005181#ifdef _SC_SPLIT_CACHE
5182 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5183#endif
5184#ifdef _SC_SSIZE_MAX
5185 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5186#endif
5187#ifdef _SC_STACK_PROT
5188 {"SC_STACK_PROT", _SC_STACK_PROT},
5189#endif
5190#ifdef _SC_STREAM_MAX
5191 {"SC_STREAM_MAX", _SC_STREAM_MAX},
5192#endif
5193#ifdef _SC_SYNCHRONIZED_IO
5194 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
5195#endif
5196#ifdef _SC_THREADS
5197 {"SC_THREADS", _SC_THREADS},
5198#endif
5199#ifdef _SC_THREAD_ATTR_STACKADDR
5200 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
5201#endif
5202#ifdef _SC_THREAD_ATTR_STACKSIZE
5203 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
5204#endif
5205#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
5206 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
5207#endif
5208#ifdef _SC_THREAD_KEYS_MAX
5209 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
5210#endif
5211#ifdef _SC_THREAD_PRIORITY_SCHEDULING
5212 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
5213#endif
5214#ifdef _SC_THREAD_PRIO_INHERIT
5215 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
5216#endif
5217#ifdef _SC_THREAD_PRIO_PROTECT
5218 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
5219#endif
5220#ifdef _SC_THREAD_PROCESS_SHARED
5221 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
5222#endif
5223#ifdef _SC_THREAD_SAFE_FUNCTIONS
5224 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
5225#endif
5226#ifdef _SC_THREAD_STACK_MIN
5227 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
5228#endif
5229#ifdef _SC_THREAD_THREADS_MAX
5230 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
5231#endif
5232#ifdef _SC_TIMERS
5233 {"SC_TIMERS", _SC_TIMERS},
5234#endif
5235#ifdef _SC_TIMER_MAX
5236 {"SC_TIMER_MAX", _SC_TIMER_MAX},
5237#endif
5238#ifdef _SC_TTY_NAME_MAX
5239 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
5240#endif
5241#ifdef _SC_TZNAME_MAX
5242 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
5243#endif
5244#ifdef _SC_T_IOV_MAX
5245 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
5246#endif
5247#ifdef _SC_UCHAR_MAX
5248 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
5249#endif
5250#ifdef _SC_UINT_MAX
5251 {"SC_UINT_MAX", _SC_UINT_MAX},
5252#endif
5253#ifdef _SC_UIO_MAXIOV
5254 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
5255#endif
5256#ifdef _SC_ULONG_MAX
5257 {"SC_ULONG_MAX", _SC_ULONG_MAX},
5258#endif
5259#ifdef _SC_USHRT_MAX
5260 {"SC_USHRT_MAX", _SC_USHRT_MAX},
5261#endif
5262#ifdef _SC_VERSION
5263 {"SC_VERSION", _SC_VERSION},
5264#endif
5265#ifdef _SC_WORD_BIT
5266 {"SC_WORD_BIT", _SC_WORD_BIT},
5267#endif
5268#ifdef _SC_XBS5_ILP32_OFF32
5269 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
5270#endif
5271#ifdef _SC_XBS5_ILP32_OFFBIG
5272 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
5273#endif
5274#ifdef _SC_XBS5_LP64_OFF64
5275 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
5276#endif
5277#ifdef _SC_XBS5_LPBIG_OFFBIG
5278 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
5279#endif
5280#ifdef _SC_XOPEN_CRYPT
5281 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
5282#endif
5283#ifdef _SC_XOPEN_ENH_I18N
5284 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
5285#endif
5286#ifdef _SC_XOPEN_LEGACY
5287 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
5288#endif
5289#ifdef _SC_XOPEN_REALTIME
5290 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
5291#endif
5292#ifdef _SC_XOPEN_REALTIME_THREADS
5293 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
5294#endif
5295#ifdef _SC_XOPEN_SHM
5296 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
5297#endif
5298#ifdef _SC_XOPEN_UNIX
5299 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
5300#endif
5301#ifdef _SC_XOPEN_VERSION
5302 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
5303#endif
5304#ifdef _SC_XOPEN_XCU_VERSION
5305 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
5306#endif
5307#ifdef _SC_XOPEN_XPG2
5308 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
5309#endif
5310#ifdef _SC_XOPEN_XPG3
5311 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
5312#endif
5313#ifdef _SC_XOPEN_XPG4
5314 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
5315#endif
5316};
5317
5318static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005319conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005320{
5321 return conv_confname(arg, valuep, posix_constants_sysconf,
5322 sizeof(posix_constants_sysconf)
5323 / sizeof(struct constdef));
5324}
5325
5326static char posix_sysconf__doc__[] = "\
5327sysconf(name) -> integer\n\
5328Return an integer-valued system configuration variable.";
5329
5330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005331posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005332{
5333 PyObject *result = NULL;
5334 int name;
5335
5336 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
5337 int value;
5338
5339 errno = 0;
5340 value = sysconf(name);
5341 if (value == -1 && errno != 0)
5342 posix_error();
5343 else
5344 result = PyInt_FromLong(value);
5345 }
5346 return result;
5347}
5348#endif
5349
5350
Fred Drakebec628d1999-12-15 18:31:10 +00005351/* This code is used to ensure that the tables of configuration value names
5352 * are in sorted order as required by conv_confname(), and also to build the
5353 * the exported dictionaries that are used to publish information about the
5354 * names available on the host platform.
5355 *
5356 * Sorting the table at runtime ensures that the table is properly ordered
5357 * when used, even for platforms we're not able to test on. It also makes
5358 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00005359 */
Fred Drakebec628d1999-12-15 18:31:10 +00005360
5361static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005362cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00005363{
5364 const struct constdef *c1 =
5365 (const struct constdef *) v1;
5366 const struct constdef *c2 =
5367 (const struct constdef *) v2;
5368
5369 return strcmp(c1->name, c2->name);
5370}
5371
5372static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005373setup_confname_table(struct constdef *table, size_t tablesize,
5374 char *tablename, PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005375{
Fred Drakebec628d1999-12-15 18:31:10 +00005376 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00005377 size_t i;
5378 int status;
Fred Drakebec628d1999-12-15 18:31:10 +00005379
5380 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
5381 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00005382 if (d == NULL)
5383 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005384
Barry Warsaw3155db32000-04-13 15:20:40 +00005385 for (i=0; i < tablesize; ++i) {
5386 PyObject *o = PyInt_FromLong(table[i].value);
5387 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
5388 Py_XDECREF(o);
5389 Py_DECREF(d);
5390 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005391 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005392 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00005393 }
Barry Warsaw3155db32000-04-13 15:20:40 +00005394 status = PyDict_SetItemString(moddict, tablename, d);
5395 Py_DECREF(d);
5396 return status;
Fred Draked86ed291999-12-15 15:34:33 +00005397}
5398
Fred Drakebec628d1999-12-15 18:31:10 +00005399/* Return -1 on failure, 0 on success. */
5400static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005401setup_confname_tables(PyObject *moddict)
Fred Draked86ed291999-12-15 15:34:33 +00005402{
5403#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00005404 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00005405 sizeof(posix_constants_pathconf)
5406 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005407 "pathconf_names", moddict))
5408 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005409#endif
5410#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00005411 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00005412 sizeof(posix_constants_confstr)
5413 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005414 "confstr_names", moddict))
5415 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005416#endif
5417#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00005418 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00005419 sizeof(posix_constants_sysconf)
5420 / sizeof(struct constdef),
Fred Drakebec628d1999-12-15 18:31:10 +00005421 "sysconf_names", moddict))
5422 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00005423#endif
Fred Drakebec628d1999-12-15 18:31:10 +00005424 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00005425}
Fred Draked86ed291999-12-15 15:34:33 +00005426
5427
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005428static char posix_abort__doc__[] = "\
5429abort() -> does not return!\n\
5430Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5431in the hardest way possible on the hosting operating system.";
5432
5433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005434posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005435{
5436 if (!PyArg_ParseTuple(args, ":abort"))
5437 return NULL;
5438 abort();
5439 /*NOTREACHED*/
5440 Py_FatalError("abort() called from Python code didn't abort!");
5441 return NULL;
5442}
Fred Drakebec628d1999-12-15 18:31:10 +00005443
Tim Petersf58a7aa2000-09-22 10:05:54 +00005444#ifdef MS_WIN32
5445static char win32_startfile__doc__[] = "\
5446startfile(filepath) - Start a file with its associated application.\n\
5447\n\
5448This acts like double-clicking the file in Explorer, or giving the file\n\
5449name as an argument to the DOS \"start\" command: the file is opened\n\
5450with whatever application (if any) its extension is associated.\n\
5451\n\
5452startfile returns as soon as the associated application is launched.\n\
5453There is no option to wait for the application to close, and no way\n\
5454to retrieve the application's exit status.\n\
5455\n\
5456The filepath is relative to the current directory. If you want to use\n\
5457an absolute path, make sure the first character is not a slash (\"/\");\n\
5458the underlying Win32 ShellExecute function doesn't work if it is.";
5459
5460static PyObject *
5461win32_startfile(PyObject *self, PyObject *args)
5462{
5463 char *filepath;
5464 HINSTANCE rc;
5465 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
5466 return NULL;
5467 Py_BEGIN_ALLOW_THREADS
5468 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
5469 Py_END_ALLOW_THREADS
5470 if (rc <= (HINSTANCE)32)
5471 return win32_error("startfile", filepath);
5472 Py_INCREF(Py_None);
5473 return Py_None;
5474}
5475#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005476
5477static PyMethodDef posix_methods[] = {
5478 {"access", posix_access, METH_VARARGS, posix_access__doc__},
5479#ifdef HAVE_TTYNAME
5480 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
5481#endif
5482 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
5483 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005484#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005485 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005486#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00005487#ifdef HAVE_CHROOT
5488 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
5489#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005490#ifdef HAVE_CTERMID
5491 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
5492#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00005493#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005494 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00005495#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005496#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005497 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005498#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005499 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
5500 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
5501 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005502#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005503 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005504#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005505#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005506 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005507#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005508 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
5509 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
5510 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005511#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005512 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005513#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005514#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005515 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005516#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005517 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005518#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005519 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005520#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005521 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
5522 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
5523 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005524#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005525 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005526#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005527 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005528#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005529 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
5530 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005531#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00005532#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005533 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
5534 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00005535#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005536#ifdef HAVE_FORK1
5537 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
5538#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005539#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005540 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005541#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005542#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005543 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00005544#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005545#ifdef HAVE_FORKPTY
5546 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
5547#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005548#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005549 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005550#endif /* HAVE_GETEGID */
5551#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005552 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005553#endif /* HAVE_GETEUID */
5554#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005555 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005556#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00005557#ifdef HAVE_GETGROUPS
5558 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
5559#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005560 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00005561#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005562 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005563#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005564#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005565 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005566#endif /* HAVE_GETPPID */
5567#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005568 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005569#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00005570#ifdef HAVE_GETLOGIN
5571 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
5572#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00005573#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005574 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005575#endif /* HAVE_KILL */
Guido van Rossumc0125471996-06-28 18:55:32 +00005576#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005577 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00005578#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005579#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005580 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005581#ifdef MS_WIN32
5582 {"popen2", win32_popen2, METH_VARARGS},
5583 {"popen3", win32_popen3, METH_VARARGS},
5584 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00005585 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005586#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005587#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005588#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005589 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005590#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005591#ifdef HAVE_SETEUID
5592 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5593#endif /* HAVE_SETEUID */
5594#ifdef HAVE_SETEGID
5595 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
5596#endif /* HAVE_SETEGID */
5597#ifdef HAVE_SETREUID
5598 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5599#endif /* HAVE_SETREUID */
5600#ifdef HAVE_SETREGID
5601 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
5602#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005603#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005604 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005605#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005606#ifdef HAVE_SETGROUPS
5607 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
5608#endif /* HAVE_SETGROUPS */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005609#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005610 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005611#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00005612#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005613 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00005614#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00005615#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005616 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005617#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005618#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005619 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005620#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005621#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005622 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005623#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005624#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005625 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005626#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005627#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005628 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005629#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005630 {"open", posix_open, METH_VARARGS, posix_open__doc__},
5631 {"close", posix_close, METH_VARARGS, posix_close__doc__},
5632 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
5633 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
5634 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
5635 {"read", posix_read, METH_VARARGS, posix_read__doc__},
5636 {"write", posix_write, METH_VARARGS, posix_write__doc__},
5637 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
5638 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00005639 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005640#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005641 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005642#endif
5643#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005644 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005645#endif
5646#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005647 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005648#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005649#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005650 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005651#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00005652#ifdef HAVE_UNSETENV
5653 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
5654#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00005655#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005656 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00005657#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00005658#ifdef HAVE_FSYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005659 {"fsync", posix_fsync, METH_VARARGS, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005660#endif
5661#ifdef HAVE_FDATASYNC
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005662 {"fdatasync", posix_fdatasync, METH_VARARGS, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00005663#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00005664#ifdef HAVE_SYS_WAIT_H
5665#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005666 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005667#endif /* WIFSTOPPED */
5668#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005669 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005670#endif /* WIFSIGNALED */
5671#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005672 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005673#endif /* WIFEXITED */
5674#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005675 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005676#endif /* WEXITSTATUS */
5677#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005678 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005679#endif /* WTERMSIG */
5680#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005681 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00005682#endif /* WSTOPSIG */
5683#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005684#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005685 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005686#endif
5687#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005688 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00005689#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00005690#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005691 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5692#endif
5693#ifdef HAVE_TEMPNAM
5694 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5695#endif
5696#ifdef HAVE_TMPNAM
5697 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5698#endif
Fred Drakec9680921999-12-13 16:37:25 +00005699#ifdef HAVE_CONFSTR
5700 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
5701#endif
5702#ifdef HAVE_SYSCONF
5703 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5704#endif
5705#ifdef HAVE_FPATHCONF
5706 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5707#endif
5708#ifdef HAVE_PATHCONF
5709 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5710#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005711 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00005712#ifdef MS_WIN32
5713 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
5714#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005715 {NULL, NULL} /* Sentinel */
5716};
5717
5718
Barry Warsaw4a342091996-12-19 23:50:02 +00005719static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005720ins(PyObject *d, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00005721{
5722 PyObject* v = PyInt_FromLong(value);
5723 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5724 return -1; /* triggers fatal error */
5725
5726 Py_DECREF(v);
5727 return 0;
5728}
5729
Guido van Rossumd48f2521997-12-05 22:19:34 +00005730#if defined(PYOS_OS2)
5731/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5732static int insertvalues(PyObject *d)
5733{
5734 APIRET rc;
5735 ULONG values[QSV_MAX+1];
5736 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00005737 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00005738
5739 Py_BEGIN_ALLOW_THREADS
5740 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5741 Py_END_ALLOW_THREADS
5742
5743 if (rc != NO_ERROR) {
5744 os2_error(rc);
5745 return -1;
5746 }
5747
5748 if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5749 if (ins(d, "memkernel", values[QSV_TOTRESMEM])) return -1;
5750 if (ins(d, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
5751 if (ins(d, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
5752 if (ins(d, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
5753 if (ins(d, "revision", values[QSV_VERSION_REVISION])) return -1;
5754 if (ins(d, "timeslice", values[QSV_MIN_SLICE])) return -1;
5755
5756 switch (values[QSV_VERSION_MINOR]) {
5757 case 0: ver = "2.00"; break;
5758 case 10: ver = "2.10"; break;
5759 case 11: ver = "2.11"; break;
5760 case 30: ver = "3.00"; break;
5761 case 40: ver = "4.00"; break;
5762 case 50: ver = "5.00"; break;
5763 default:
Tim Peters885d4572001-11-28 20:27:42 +00005764 PyOS_snprintf(tmp, sizeof(tmp),
5765 "%d-%d", values[QSV_VERSION_MAJOR],
5766 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00005767 ver = &tmp[0];
5768 }
5769
5770 /* Add Indicator of the Version of the Operating System */
5771 v = PyString_FromString(ver);
5772 if (!v || PyDict_SetItemString(d, "version", v) < 0)
5773 return -1;
5774 Py_DECREF(v);
5775
5776 /* Add Indicator of Which Drive was Used to Boot the System */
5777 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5778 tmp[1] = ':';
5779 tmp[2] = '\0';
5780
5781 v = PyString_FromString(tmp);
5782 if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5783 return -1;
5784 Py_DECREF(v);
5785
5786 return 0;
5787}
5788#endif
5789
Barry Warsaw4a342091996-12-19 23:50:02 +00005790static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005791all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00005792{
Guido van Rossum94f6f721999-01-06 18:42:14 +00005793#ifdef F_OK
5794 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005795#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005796#ifdef R_OK
5797 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005798#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005799#ifdef W_OK
5800 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005801#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005802#ifdef X_OK
5803 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005804#endif
Fred Drakec9680921999-12-13 16:37:25 +00005805#ifdef NGROUPS_MAX
5806 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5807#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005808#ifdef TMP_MAX
5809 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5810#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005811#ifdef WNOHANG
5812 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00005813#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005814#ifdef O_RDONLY
5815 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5816#endif
5817#ifdef O_WRONLY
5818 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5819#endif
5820#ifdef O_RDWR
5821 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5822#endif
5823#ifdef O_NDELAY
5824 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5825#endif
5826#ifdef O_NONBLOCK
5827 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5828#endif
5829#ifdef O_APPEND
5830 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5831#endif
5832#ifdef O_DSYNC
5833 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5834#endif
5835#ifdef O_RSYNC
5836 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5837#endif
5838#ifdef O_SYNC
5839 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5840#endif
5841#ifdef O_NOCTTY
5842 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5843#endif
5844#ifdef O_CREAT
5845 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5846#endif
5847#ifdef O_EXCL
5848 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5849#endif
5850#ifdef O_TRUNC
5851 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5852#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00005853#ifdef O_BINARY
5854 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5855#endif
5856#ifdef O_TEXT
5857 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5858#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005859#ifdef O_LARGEFILE
5860 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
5861#endif
5862
Tim Peters5aa91602002-01-30 05:46:57 +00005863/* MS Windows */
5864#ifdef O_NOINHERIT
5865 /* Don't inherit in child processes. */
5866 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
5867#endif
5868#ifdef _O_SHORT_LIVED
5869 /* Optimize for short life (keep in memory). */
5870 /* MS forgot to define this one with a non-underscore form too. */
5871 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
5872#endif
5873#ifdef O_TEMPORARY
5874 /* Automatically delete when last handle is closed. */
5875 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
5876#endif
5877#ifdef O_RANDOM
5878 /* Optimize for random access. */
5879 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
5880#endif
5881#ifdef O_SEQUENTIAL
5882 /* Optimize for sequential access. */
5883 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
5884#endif
5885
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00005886/* GNU extensions. */
5887#ifdef O_DIRECT
5888 /* Direct disk access. */
5889 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
5890#endif
5891#ifdef O_DIRECTORY
5892 /* Must be a directory. */
5893 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
5894#endif
5895#ifdef O_NOFOLLOW
5896 /* Do not follow links. */
5897 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
5898#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00005899
Guido van Rossum246bc171999-02-01 23:54:31 +00005900#ifdef HAVE_SPAWNV
Guido van Rossum7d385291999-02-16 19:38:04 +00005901 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5902 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5903 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5904 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5905 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00005906#endif
5907
Guido van Rossumd48f2521997-12-05 22:19:34 +00005908#if defined(PYOS_OS2)
5909 if (insertvalues(d)) return -1;
5910#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00005911 return 0;
5912}
5913
5914
Tim Peters5aa91602002-01-30 05:46:57 +00005915#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005916#define INITFUNC initnt
5917#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005918
5919#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005920#define INITFUNC initos2
5921#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00005922
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005923#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005924#define INITFUNC initposix
5925#define MODNAME "posix"
5926#endif
5927
Guido van Rossum3886bb61998-12-04 18:50:17 +00005928DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005929INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00005930{
Barry Warsaw53699e91996-12-10 23:23:01 +00005931 PyObject *m, *d, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00005932
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005933 m = Py_InitModule4(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005934 posix_methods,
5935 posix__doc__,
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005936 (PyObject *)NULL,
5937 PYTHON_API_VERSION);
Barry Warsaw53699e91996-12-10 23:23:01 +00005938 d = PyModule_GetDict(m);
Tim Peters5aa91602002-01-30 05:46:57 +00005939
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005940 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005941 v = convertenviron();
Barry Warsaw53699e91996-12-10 23:23:01 +00005942 if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00005943 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00005944 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00005945
Barry Warsaw4a342091996-12-19 23:50:02 +00005946 if (all_ins(d))
Barry Warsaw4a342091996-12-19 23:50:02 +00005947 return;
5948
Fred Drakebec628d1999-12-15 18:31:10 +00005949 if (setup_confname_tables(d))
5950 return;
5951
Barry Warsawca74da41999-02-09 19:31:45 +00005952 PyDict_SetItemString(d, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00005953
Guido van Rossumb3d39562000-01-31 18:41:26 +00005954#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00005955 if (posix_putenv_garbage == NULL)
5956 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00005957#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005958
Guido van Rossum14648392001-12-08 18:02:58 +00005959 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005960 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
5961 PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
5962
Guido van Rossum14648392001-12-08 18:02:58 +00005963 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005964 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Guido van Rossumbb2501f2001-12-27 16:23:28 +00005965 PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005966}