blob: 2a77ee3c2c1166755b214c8ba8c61f223ed5a974 [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
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are 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
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
19PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000020"This module provides access to operating system functionality that is\n\
21standardized by the C Standard and the POSIX standard (a thinly\n\
22disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000024
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000025#if defined(PYOS_OS2)
26#define INCL_DOS
27#define INCL_DOSERRORS
28#define INCL_DOSPROCESS
29#define INCL_NOPMAPI
30#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000031#if defined(PYCC_GCC)
32#include <ctype.h>
33#include <io.h>
34#include <stdio.h>
35#include <process.h>
36#include "osdefs.h"
37#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000038#endif
39
Guido van Rossumb6775db1994-08-01 11:34:53 +000040#include <sys/types.h>
41#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000042
Guido van Rossum36bc6801995-06-14 22:54:23 +000043#ifdef HAVE_SYS_WAIT_H
44#include <sys/wait.h> /* For WNOHANG */
45#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000046
Guido van Rossuma376cc51996-12-05 23:43:35 +000047#ifdef HAVE_SIGNAL_H
48#include <signal.h>
49#endif
50
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#ifdef HAVE_FCNTL_H
52#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000053#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000054
Guido van Rossuma6535fd2001-10-18 19:44:10 +000055#ifdef HAVE_GRP_H
56#include <grp.h>
57#endif
58
Guido van Rossuma4916fa1996-05-23 22:58:55 +000059/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000060/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000061#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000062#include <process.h>
63#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000064#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000065#define HAVE_GETCWD 1
66#define HAVE_OPENDIR 1
67#define HAVE_SYSTEM 1
68#if defined(__OS2__)
69#define HAVE_EXECV 1
70#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000071#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000072#include <process.h>
73#else
74#ifdef __BORLANDC__ /* Borland compiler */
75#define HAVE_EXECV 1
76#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000077#define HAVE_OPENDIR 1
78#define HAVE_PIPE 1
79#define HAVE_POPEN 1
80#define HAVE_SYSTEM 1
81#define HAVE_WAIT 1
82#else
83#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000084#define HAVE_GETCWD 1
85#ifdef MS_WIN32
Guido van Rossuma1065681999-01-25 23:20:23 +000086#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000087#define HAVE_EXECV 1
88#define HAVE_PIPE 1
89#define HAVE_POPEN 1
90#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000091#define HAVE_CWAIT 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092#else /* 16-bit Windows */
Guido van Rossum8d665e61996-06-26 18:22:49 +000093#endif /* !MS_WIN32 */
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000094#else
95#if defined(PYOS_OS2) && defined(PYCC_GCC)
96/* Everything needed is defined in PC/os2emx/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000097#else /* all other compilers */
98/* Unix functions that the configure script doesn't check for */
99#define HAVE_EXECV 1
100#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000101#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
102#define HAVE_FORK1 1
103#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000104#define HAVE_GETCWD 1
105#define HAVE_GETEGID 1
106#define HAVE_GETEUID 1
107#define HAVE_GETGID 1
108#define HAVE_GETPPID 1
109#define HAVE_GETUID 1
110#define HAVE_KILL 1
111#define HAVE_OPENDIR 1
112#define HAVE_PIPE 1
113#define HAVE_POPEN 1
114#define HAVE_SYSTEM 1
115#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000116#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000117#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#endif /* _MSC_VER */
119#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000120#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000121#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000122
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000123#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000124
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000125#if defined(sun) && !defined(__SVR4)
126/* SunOS 4.1.4 doesn't have prototypes for these: */
127extern int rename(const char *, const char *);
128extern int pclose(FILE *);
129extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000130extern int fsync(int);
131extern int lstat(const char *, struct stat *);
132extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000133#endif
134
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000135#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000136#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000138#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000139#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000142extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000144#endif
145#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(char *);
147extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(const char *);
150extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000152#ifdef __BORLANDC__
153extern int chmod(const char *, int);
154#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000155extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000156#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int chown(const char *, uid_t, gid_t);
158extern char *getcwd(char *, int);
159extern char *strerror(int);
160extern int link(const char *, const char *);
161extern int rename(const char *, const char *);
162extern int stat(const char *, struct stat *);
163extern int unlink(const char *);
164extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000167#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000170#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000172
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175#ifdef HAVE_UTIME_H
176#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000177#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000179#ifdef HAVE_SYS_UTIME_H
180#include <sys/utime.h>
181#define HAVE_UTIME_H /* pretend we do for the rest of this file */
182#endif /* HAVE_SYS_UTIME_H */
183
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184#ifdef HAVE_SYS_TIMES_H
185#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000186#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187
188#ifdef HAVE_SYS_PARAM_H
189#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000190#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000191
192#ifdef HAVE_SYS_UTSNAME_H
193#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000194#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000196#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000197#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000198#define NAMLEN(dirent) strlen((dirent)->d_name)
199#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000200#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#include <direct.h>
202#define NAMLEN(dirent) strlen((dirent)->d_name)
203#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000204#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000205#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000206#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000207#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#include <direct.h>
220#include <io.h>
221#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000222#include "osdefs.h"
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000223#define WINDOWS_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <windows.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000225#ifdef MS_WIN32
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000227#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#else /* 16-bit Windows */
229#include <dos.h>
230#include <ctype.h>
Guido van Rossum8d665e61996-06-26 18:22:49 +0000231#endif /* MS_WIN32 */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233
Guido van Rossumd48f2521997-12-05 22:19:34 +0000234#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000236#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
Tim Petersbc2e10e2002-03-03 23:17:02 +0000238#ifndef MAXPATHLEN
239#define MAXPATHLEN 1024
240#endif /* MAXPATHLEN */
241
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000242#ifdef UNION_WAIT
243/* Emulate some macros on systems that have a union instead of macros */
244
245#ifndef WIFEXITED
246#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
247#endif
248
249#ifndef WEXITSTATUS
250#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
251#endif
252
253#ifndef WTERMSIG
254#define WTERMSIG(u_wait) ((u_wait).w_termsig)
255#endif
256
257#endif /* UNION_WAIT */
258
Greg Wardb48bc172000-03-01 21:51:56 +0000259/* Don't use the "_r" form if we don't need it (also, won't have a
260 prototype for it, at least on Solaris -- maybe others as well?). */
261#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
262#define USE_CTERMID_R
263#endif
264
265#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
266#define USE_TMPNAM_R
267#endif
268
Fred Drake699f3522000-06-29 21:12:41 +0000269/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000270#undef STAT
Tim Peters6e13a562001-09-06 00:32:15 +0000271#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +0000272# define STAT _stati64
273# define FSTAT _fstati64
274# define STRUCT_STAT struct _stati64
275#else
276# define STAT stat
277# define FSTAT fstat
278# define STRUCT_STAT struct stat
279#endif
280
Neal Norwitz3d949422002-04-20 13:46:43 +0000281#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
282#include <sys/mkdev.h>
283#endif
Fred Drake699f3522000-06-29 21:12:41 +0000284
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285/* Return a dictionary corresponding to the POSIX environment table */
286
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000287#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000289#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290
Barry Warsaw53699e91996-12-10 23:23:01 +0000291static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000292convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293{
Barry Warsaw53699e91996-12-10 23:23:01 +0000294 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000296 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297 if (d == NULL)
298 return NULL;
299 if (environ == NULL)
300 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000301 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000303 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000304 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000305 char *p = strchr(*e, '=');
306 if (p == NULL)
307 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000308 k = PyString_FromStringAndSize(*e, (int)(p-*e));
309 if (k == NULL) {
310 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000312 }
313 v = PyString_FromString(p+1);
314 if (v == NULL) {
315 PyErr_Clear();
316 Py_DECREF(k);
317 continue;
318 }
319 if (PyDict_GetItem(d, k) == NULL) {
320 if (PyDict_SetItem(d, k, v) != 0)
321 PyErr_Clear();
322 }
323 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000324 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000326#if defined(PYOS_OS2)
327 {
328 APIRET rc;
329 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
330
331 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000332 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000333 PyObject *v = PyString_FromString(buffer);
334 PyDict_SetItemString(d, "BEGINLIBPATH", v);
335 Py_DECREF(v);
336 }
337 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
338 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
339 PyObject *v = PyString_FromString(buffer);
340 PyDict_SetItemString(d, "ENDLIBPATH", v);
341 Py_DECREF(v);
342 }
343 }
344#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 return d;
346}
347
348
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349/* Set a POSIX-specific error from errno, and return NULL */
350
Barry Warsawd58d7641998-07-23 16:14:40 +0000351static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000352posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000353{
Barry Warsawca74da41999-02-09 19:31:45 +0000354 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000355}
Barry Warsawd58d7641998-07-23 16:14:40 +0000356static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000357posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000358{
Barry Warsawca74da41999-02-09 19:31:45 +0000359 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000360}
361
Mark Hammondef8b6542001-05-13 08:04:26 +0000362static PyObject *
363posix_error_with_allocated_filename(char* name)
364{
365 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
366 PyMem_Free(name);
367 return rc;
368}
369
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000370#ifdef MS_WIN32
371static PyObject *
372win32_error(char* function, char* filename)
373{
Mark Hammond33a6da92000-08-15 00:46:38 +0000374 /* XXX We should pass the function name along in the future.
375 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000376 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000377 Windows error object, which is non-trivial.
378 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000379 errno = GetLastError();
380 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000381 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000382 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000383 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000384}
385#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000386
Guido van Rossumd48f2521997-12-05 22:19:34 +0000387#if defined(PYOS_OS2)
388/**********************************************************************
389 * Helper Function to Trim and Format OS/2 Messages
390 **********************************************************************/
391 static void
392os2_formatmsg(char *msgbuf, int msglen, char *reason)
393{
394 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
395
396 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
397 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
398
399 while (lastc > msgbuf && isspace(*lastc))
400 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
401 }
402
403 /* Add Optional Reason Text */
404 if (reason) {
405 strcat(msgbuf, " : ");
406 strcat(msgbuf, reason);
407 }
408}
409
410/**********************************************************************
411 * Decode an OS/2 Operating System Error Code
412 *
413 * A convenience function to lookup an OS/2 error code and return a
414 * text message we can use to raise a Python exception.
415 *
416 * Notes:
417 * The messages for errors returned from the OS/2 kernel reside in
418 * the file OSO001.MSG in the \OS2 directory hierarchy.
419 *
420 **********************************************************************/
421 static char *
422os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
423{
424 APIRET rc;
425 ULONG msglen;
426
427 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
428 Py_BEGIN_ALLOW_THREADS
429 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
430 errorcode, "oso001.msg", &msglen);
431 Py_END_ALLOW_THREADS
432
433 if (rc == NO_ERROR)
434 os2_formatmsg(msgbuf, msglen, reason);
435 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000436 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000437 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000438
439 return msgbuf;
440}
441
442/* Set an OS/2-specific error and return NULL. OS/2 kernel
443 errors are not in a global variable e.g. 'errno' nor are
444 they congruent with posix error numbers. */
445
446static PyObject * os2_error(int code)
447{
448 char text[1024];
449 PyObject *v;
450
451 os2_strerror(text, sizeof(text), code, "");
452
453 v = Py_BuildValue("(is)", code, text);
454 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000455 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000456 Py_DECREF(v);
457 }
458 return NULL; /* Signal to Python that an Exception is Pending */
459}
460
461#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000462
463/* POSIX generic methods */
464
Barry Warsaw53699e91996-12-10 23:23:01 +0000465static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000466posix_fildes(PyObject *fdobj, int (*func)(int))
467{
468 int fd;
469 int res;
470 fd = PyObject_AsFileDescriptor(fdobj);
471 if (fd < 0)
472 return NULL;
473 Py_BEGIN_ALLOW_THREADS
474 res = (*func)(fd);
475 Py_END_ALLOW_THREADS
476 if (res < 0)
477 return posix_error();
478 Py_INCREF(Py_None);
479 return Py_None;
480}
Guido van Rossum21142a01999-01-08 21:05:37 +0000481
482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000483posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000484{
Mark Hammondef8b6542001-05-13 08:04:26 +0000485 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000486 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000487 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000488 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000490 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000491 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000492 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000493 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000494 return posix_error_with_allocated_filename(path1);
495 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000496 Py_INCREF(Py_None);
497 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000498}
499
Barry Warsaw53699e91996-12-10 23:23:01 +0000500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000501posix_2str(PyObject *args, char *format,
502 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000503{
Mark Hammondef8b6542001-05-13 08:04:26 +0000504 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000505 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000506 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000507 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000508 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000510 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000511 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000512 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000513 PyMem_Free(path1);
514 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000515 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000516 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000518 Py_INCREF(Py_None);
519 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000520}
521
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000522PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000523"stat_result: Result from stat or lstat.\n\n\
524This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000525 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000526or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
527\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000528Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000529they are available as attributes only.\n\
530\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000531See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000532
533static PyStructSequence_Field stat_result_fields[] = {
534 {"st_mode", "protection bits"},
535 {"st_ino", "inode"},
536 {"st_dev", "device"},
537 {"st_nlink", "number of hard links"},
538 {"st_uid", "user ID of owner"},
539 {"st_gid", "group ID of owner"},
540 {"st_size", "total size, in bytes"},
541 {"st_atime", "time of last access"},
542 {"st_mtime", "time of last modification"},
543 {"st_ctime", "time of last change"},
544#ifdef HAVE_ST_BLKSIZE
545 {"st_blksize", "blocksize for filesystem I/O"},
546#endif
547#ifdef HAVE_ST_BLOCKS
548 {"st_blocks", "number of blocks allocated"},
549#endif
550#ifdef HAVE_ST_RDEV
551 {"st_rdev", "device type (if inode device)"},
552#endif
553 {0}
554};
555
556#ifdef HAVE_ST_BLKSIZE
557#define ST_BLKSIZE_IDX 10
558#else
559#define ST_BLKSIZE_IDX 9
560#endif
561
562#ifdef HAVE_ST_BLOCKS
563#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
564#else
565#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
566#endif
567
568#ifdef HAVE_ST_RDEV
569#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
570#else
571#define ST_RDEV_IDX ST_BLOCKS_IDX
572#endif
573
574static PyStructSequence_Desc stat_result_desc = {
575 "stat_result", /* name */
576 stat_result__doc__, /* doc */
577 stat_result_fields,
578 10
579};
580
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000581PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000582"statvfs_result: Result from statvfs or fstatvfs.\n\n\
583This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000584 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000585or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000586\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000587See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000588
589static PyStructSequence_Field statvfs_result_fields[] = {
590 {"f_bsize", },
591 {"f_frsize", },
592 {"f_blocks", },
593 {"f_bfree", },
594 {"f_bavail", },
595 {"f_files", },
596 {"f_ffree", },
597 {"f_favail", },
598 {"f_flag", },
599 {"f_namemax",},
600 {0}
601};
602
603static PyStructSequence_Desc statvfs_result_desc = {
604 "statvfs_result", /* name */
605 statvfs_result__doc__, /* doc */
606 statvfs_result_fields,
607 10
608};
609
610static PyTypeObject StatResultType;
611static PyTypeObject StatVFSResultType;
612
Tim Peters5aa91602002-01-30 05:46:57 +0000613/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000614 (used by posix_stat() and posix_fstat()) */
615static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000616_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000617{
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000618 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000619 if (v == NULL)
620 return NULL;
621
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000622 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000623#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000624 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000625 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000626#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000627 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000628#endif
629#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000630 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000631 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000632#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000633 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000634#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000635 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
636 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
637 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000638#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000639 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000640 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000641#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000642 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000643#endif
644#if SIZEOF_TIME_T > SIZEOF_LONG
Tim Peters5aa91602002-01-30 05:46:57 +0000645 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000646 PyLong_FromLongLong((LONG_LONG)st.st_atime));
Tim Peters5aa91602002-01-30 05:46:57 +0000647 PyStructSequence_SET_ITEM(v, 8,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000648 PyLong_FromLongLong((LONG_LONG)st.st_mtime));
Tim Peters5aa91602002-01-30 05:46:57 +0000649 PyStructSequence_SET_ITEM(v, 9,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000650 PyLong_FromLongLong((LONG_LONG)st.st_ctime));
Fred Drake699f3522000-06-29 21:12:41 +0000651#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000652 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
653 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
654 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
655#endif
656
657#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000658 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000659 PyInt_FromLong((long)st.st_blksize));
660#endif
661#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000662 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000663 PyInt_FromLong((long)st.st_blocks));
664#endif
665#ifdef HAVE_ST_RDEV
666 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
667 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000668#endif
669
670 if (PyErr_Occurred()) {
671 Py_DECREF(v);
672 return NULL;
673 }
674
675 return v;
676}
677
Barry Warsaw53699e91996-12-10 23:23:01 +0000678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000679posix_do_stat(PyObject *self, PyObject *args, char *format,
680 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000681{
Fred Drake699f3522000-06-29 21:12:41 +0000682 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000683 char *path = NULL; /* pass this to stat; do not free() it */
684 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000685 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000686
687#ifdef MS_WIN32
Tim Peters500bd032001-12-19 19:05:01 +0000688 int pathlen;
689 char pathcopy[MAX_PATH];
Guido van Rossumace88ae2000-04-21 18:54:45 +0000690#endif /* MS_WIN32 */
691
Tim Peters5aa91602002-01-30 05:46:57 +0000692 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000693 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000695 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000696
697#ifdef MS_WIN32
698 pathlen = strlen(path);
699 /* the library call can blow up if the file name is too long! */
700 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000701 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000702 errno = ENAMETOOLONG;
703 return posix_error();
704 }
705
Tim Peters500bd032001-12-19 19:05:01 +0000706 /* Remove trailing slash or backslash, unless it's the current
707 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
708 */
709 if (pathlen > 0 &&
710 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
711 /* It does end with a slash -- exempt the root drive cases. */
712 /* XXX UNC root drives should also be exempted? */
713 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
714 /* leave it alone */;
715 else {
716 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000717 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000718 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000719 path = pathcopy;
720 }
721 }
722#endif /* MS_WIN32 */
723
Barry Warsaw53699e91996-12-10 23:23:01 +0000724 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000725 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000726 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000727 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000728 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000729
Tim Peters500bd032001-12-19 19:05:01 +0000730 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000731 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000732}
733
734
735/* POSIX methods */
736
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000737PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000738"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000739Use the real uid/gid to test for access to a path. Note that most\n\
740operations will use the effective uid/gid, therefore this routine can\n\
741be used in a suid/sgid environment to test if the invoking user has the\n\
742specified access to the path. The mode argument can be F_OK to test\n\
743existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000744
745static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000746posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000747{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000748 char *path;
749 int mode;
750 int res;
751
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000752 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000753 return NULL;
754 Py_BEGIN_ALLOW_THREADS
755 res = access(path, mode);
756 Py_END_ALLOW_THREADS
757 return(PyInt_FromLong(res == 0 ? 1L : 0L));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000758}
759
Guido van Rossumd371ff11999-01-25 16:12:23 +0000760#ifndef F_OK
761#define F_OK 0
762#endif
763#ifndef R_OK
764#define R_OK 4
765#endif
766#ifndef W_OK
767#define W_OK 2
768#endif
769#ifndef X_OK
770#define X_OK 1
771#endif
772
773#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000774PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000775"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000776Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000777
778static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000779posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000780{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000781 int id;
782 char *ret;
783
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000784 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000785 return NULL;
786
Guido van Rossum94f6f721999-01-06 18:42:14 +0000787 ret = ttyname(id);
788 if (ret == NULL)
789 return(posix_error());
790 return(PyString_FromString(ret));
791}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000792#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000793
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000794#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000795PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000796"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000797Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000798
799static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000800posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000801{
802 char *ret;
803 char buffer[L_ctermid];
804
805 if (!PyArg_ParseTuple(args, ":ctermid"))
806 return NULL;
807
Greg Wardb48bc172000-03-01 21:51:56 +0000808#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000809 ret = ctermid_r(buffer);
810#else
811 ret = ctermid(buffer);
812#endif
813 if (ret == NULL)
814 return(posix_error());
815 return(PyString_FromString(buffer));
816}
817#endif
818
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000819PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000820"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000821Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000822
Barry Warsaw53699e91996-12-10 23:23:01 +0000823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000824posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000825{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000826#if defined(PYOS_OS2) && defined(PYCC_GCC)
827 return posix_1str(args, "et:chdir", _chdir2);
828#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000829 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000830#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000831}
832
Fred Drake4d1e64b2002-04-15 19:40:07 +0000833#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000834PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000835"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +0000836Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000837opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +0000838
839static PyObject *
840posix_fchdir(PyObject *self, PyObject *fdobj)
841{
842 return posix_fildes(fdobj, fchdir);
843}
844#endif /* HAVE_FCHDIR */
845
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000846
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000847PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000848"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000849Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000850
Barry Warsaw53699e91996-12-10 23:23:01 +0000851static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000852posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000853{
Mark Hammondef8b6542001-05-13 08:04:26 +0000854 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000855 int i;
856 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000857 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000858 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000859 return NULL;
860 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000861 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000862 Py_END_ALLOW_THREADS
863 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000864 return posix_error_with_allocated_filename(path);
865 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000866 Py_INCREF(Py_None);
867 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000868}
869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000870
Martin v. Löwis244edc82001-10-04 22:44:26 +0000871#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000872PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000873"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000874Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +0000875
876static PyObject *
877posix_chroot(PyObject *self, PyObject *args)
878{
879 return posix_1str(args, "et:chroot", chroot);
880}
881#endif
882
Guido van Rossum21142a01999-01-08 21:05:37 +0000883#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000884PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000885"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000886force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000887
888static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000889posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000890{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000891 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000892}
893#endif /* HAVE_FSYNC */
894
895#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000896
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000897#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000898extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
899#endif
900
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000901PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000902"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +0000903force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000904 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000905
906static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000907posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000908{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000909 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000910}
911#endif /* HAVE_FDATASYNC */
912
913
Fredrik Lundh10723342000-07-10 16:38:09 +0000914#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000915PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000916"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000917Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000918
Barry Warsaw53699e91996-12-10 23:23:01 +0000919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000920posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000921{
Mark Hammondef8b6542001-05-13 08:04:26 +0000922 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000923 int uid, gid;
924 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000925 if (!PyArg_ParseTuple(args, "etii:chown",
926 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000927 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000928 return NULL;
929 Py_BEGIN_ALLOW_THREADS
930 res = chown(path, (uid_t) uid, (gid_t) gid);
931 Py_END_ALLOW_THREADS
932 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000933 return posix_error_with_allocated_filename(path);
934 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000935 Py_INCREF(Py_None);
936 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000937}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000938#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000939
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000940
Guido van Rossum36bc6801995-06-14 22:54:23 +0000941#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000942PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000943"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000944Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000945
Barry Warsaw53699e91996-12-10 23:23:01 +0000946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000947posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000948{
949 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000950 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000951 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000952 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000953 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000954#if defined(PYOS_OS2) && defined(PYCC_GCC)
955 res = _getcwd2(buf, sizeof buf);
956#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000957 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000958#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000959 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000960 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000961 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000962 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000963}
Guido van Rossum36bc6801995-06-14 22:54:23 +0000964#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000966
Guido van Rossumb6775db1994-08-01 11:34:53 +0000967#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000968PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000969"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000970Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000971
Barry Warsaw53699e91996-12-10 23:23:01 +0000972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000973posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000974{
Mark Hammondef8b6542001-05-13 08:04:26 +0000975 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000976}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000977#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000979
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000980PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000981"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000982Return a list containing the names of the entries in the directory.\n\
983\n\
984 path: path of directory to list\n\
985\n\
986The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000987entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000988
Barry Warsaw53699e91996-12-10 23:23:01 +0000989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000990posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000991{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000992 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +0000993 in separate files instead of having them all here... */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000994#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000995
Barry Warsaw53699e91996-12-10 23:23:01 +0000996 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000997 HANDLE hFindFile;
998 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +0000999 /* MAX_PATH characters could mean a bigger encoded string */
1000 char namebuf[MAX_PATH*2+5];
1001 char *bufptr = namebuf;
1002 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001003
Tim Peters5aa91602002-01-30 05:46:57 +00001004 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001005 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001006 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001007 if (len > 0) {
1008 char ch = namebuf[len-1];
1009 if (ch != SEP && ch != ALTSEP && ch != ':')
1010 namebuf[len++] = '/';
1011 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001012 strcpy(namebuf + len, "*.*");
1013
Barry Warsaw53699e91996-12-10 23:23:01 +00001014 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001015 return NULL;
1016
1017 hFindFile = FindFirstFile(namebuf, &FileData);
1018 if (hFindFile == INVALID_HANDLE_VALUE) {
1019 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001020 if (errno == ERROR_FILE_NOT_FOUND)
1021 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001022 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001023 }
1024 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001025 if (FileData.cFileName[0] == '.' &&
1026 (FileData.cFileName[1] == '\0' ||
1027 FileData.cFileName[1] == '.' &&
1028 FileData.cFileName[2] == '\0'))
1029 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001030 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001031 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001032 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001033 d = NULL;
1034 break;
1035 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001036 if (PyList_Append(d, v) != 0) {
1037 Py_DECREF(v);
1038 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001039 d = NULL;
1040 break;
1041 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001042 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001043 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1044
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001045 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001046 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001047
1048 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001049
Tim Peters0bb44a42000-09-15 07:44:49 +00001050#elif defined(_MSC_VER) /* 16-bit Windows */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001051
1052#ifndef MAX_PATH
1053#define MAX_PATH 250
1054#endif
1055 char *name, *pt;
1056 int len;
Barry Warsaw53699e91996-12-10 23:23:01 +00001057 PyObject *d, *v;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001058 char namebuf[MAX_PATH+5];
1059 struct _find_t ep;
1060
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001061 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001062 return NULL;
1063 if (len >= MAX_PATH) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001064 PyErr_SetString(PyExc_ValueError, "path too long");
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001065 return NULL;
1066 }
1067 strcpy(namebuf, name);
1068 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001069 if (*pt == ALTSEP)
1070 *pt = SEP;
1071 if (namebuf[len-1] != SEP)
1072 namebuf[len++] = SEP;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001073 strcpy(namebuf + len, "*.*");
1074
Barry Warsaw53699e91996-12-10 23:23:01 +00001075 if ((d = PyList_New(0)) == NULL)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001076 return NULL;
1077
1078 if (_dos_findfirst(namebuf, _A_RDONLY |
Barry Warsaw43d68b81996-12-19 22:10:44 +00001079 _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
1080 {
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001081 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001082 return posix_error_with_filename(name);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001083 }
1084 do {
1085 if (ep.name[0] == '.' &&
1086 (ep.name[1] == '\0' ||
1087 ep.name[1] == '.' &&
1088 ep.name[2] == '\0'))
1089 continue;
1090 strcpy(namebuf, ep.name);
1091 for (pt = namebuf; *pt; pt++)
1092 if (isupper(*pt))
1093 *pt = tolower(*pt);
Barry Warsaw53699e91996-12-10 23:23:01 +00001094 v = PyString_FromString(namebuf);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001095 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001096 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001097 d = NULL;
1098 break;
1099 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001100 if (PyList_Append(d, v) != 0) {
1101 Py_DECREF(v);
1102 Py_DECREF(d);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001103 d = NULL;
1104 break;
1105 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001106 Py_DECREF(v);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001107 } while (_dos_findnext(&ep) == 0);
1108
1109 return d;
1110
Tim Peters0bb44a42000-09-15 07:44:49 +00001111#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001112
1113#ifndef MAX_PATH
1114#define MAX_PATH CCHMAXPATH
1115#endif
1116 char *name, *pt;
1117 int len;
1118 PyObject *d, *v;
1119 char namebuf[MAX_PATH+5];
1120 HDIR hdir = 1;
1121 ULONG srchcnt = 1;
1122 FILEFINDBUF3 ep;
1123 APIRET rc;
1124
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001125 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001126 return NULL;
1127 if (len >= MAX_PATH) {
1128 PyErr_SetString(PyExc_ValueError, "path too long");
1129 return NULL;
1130 }
1131 strcpy(namebuf, name);
1132 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001133 if (*pt == ALTSEP)
1134 *pt = SEP;
1135 if (namebuf[len-1] != SEP)
1136 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001137 strcpy(namebuf + len, "*.*");
1138
1139 if ((d = PyList_New(0)) == NULL)
1140 return NULL;
1141
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001142 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1143 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001144 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001145 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1146 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1147 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001148
1149 if (rc != NO_ERROR) {
1150 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001151 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001152 }
1153
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001154 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001155 do {
1156 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001157 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001158 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001159
1160 strcpy(namebuf, ep.achName);
1161
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001162 /* Leave Case of Name Alone -- In Native Form */
1163 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001164
1165 v = PyString_FromString(namebuf);
1166 if (v == NULL) {
1167 Py_DECREF(d);
1168 d = NULL;
1169 break;
1170 }
1171 if (PyList_Append(d, v) != 0) {
1172 Py_DECREF(v);
1173 Py_DECREF(d);
1174 d = NULL;
1175 break;
1176 }
1177 Py_DECREF(v);
1178 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1179 }
1180
1181 return d;
1182#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001183
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001184 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001185 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001186 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001187 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001188 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001190 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001191 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001192 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001193 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001194 closedir(dirp);
1195 return NULL;
1196 }
1197 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001198 if (ep->d_name[0] == '.' &&
1199 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001200 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001201 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001202 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001203 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001204 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001205 d = NULL;
1206 break;
1207 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001208 if (PyList_Append(d, v) != 0) {
1209 Py_DECREF(v);
1210 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211 d = NULL;
1212 break;
1213 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001214 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215 }
1216 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001217
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001219
Tim Peters0bb44a42000-09-15 07:44:49 +00001220#endif /* which OS */
1221} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001222
Mark Hammondef8b6542001-05-13 08:04:26 +00001223#ifdef MS_WIN32
1224/* A helper function for abspath on win32 */
1225static PyObject *
1226posix__getfullpathname(PyObject *self, PyObject *args)
1227{
1228 /* assume encoded strings wont more than double no of chars */
1229 char inbuf[MAX_PATH*2];
1230 char *inbufp = inbuf;
1231 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1232 char outbuf[MAX_PATH*2];
1233 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001234 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1235 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001236 &insize))
1237 return NULL;
1238 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1239 outbuf, &temp))
1240 return win32_error("GetFullPathName", inbuf);
1241 return PyString_FromString(outbuf);
1242} /* end of posix__getfullpathname */
1243#endif /* MS_WIN32 */
1244
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001245PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001246"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001247Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001248
Barry Warsaw53699e91996-12-10 23:23:01 +00001249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001250posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001252 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001253 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001254 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001255 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001256 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001257 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001258 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001259#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001260 res = mkdir(path);
1261#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001262 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001263#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001264 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001265 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001266 return posix_error_with_allocated_filename(path);
1267 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001268 Py_INCREF(Py_None);
1269 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001270}
1271
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001272
Guido van Rossumb6775db1994-08-01 11:34:53 +00001273#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001274#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1275#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1276#include <sys/resource.h>
1277#endif
1278#endif
1279
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001280PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001281"nice(inc) -> new_priority\n\n\
1282Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001283
Barry Warsaw53699e91996-12-10 23:23:01 +00001284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001285posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001286{
1287 int increment, value;
1288
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001289 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001290 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001291
1292 /* There are two flavours of 'nice': one that returns the new
1293 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001294 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1295 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001296
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001297 If we are of the nice family that returns the new priority, we
1298 need to clear errno before the call, and check if errno is filled
1299 before calling posix_error() on a returnvalue of -1, because the
1300 -1 may be the actual new priority! */
1301
1302 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001303 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001304#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001305 if (value == 0)
1306 value = getpriority(PRIO_PROCESS, 0);
1307#endif
1308 if (value == -1 && errno != 0)
1309 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001310 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001311 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001312}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001313#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001315
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001316PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001317"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001318Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001319
Barry Warsaw53699e91996-12-10 23:23:01 +00001320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001321posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001322{
Mark Hammondef8b6542001-05-13 08:04:26 +00001323 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001324}
1325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001326
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001327PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001328"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001329Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001330
Barry Warsaw53699e91996-12-10 23:23:01 +00001331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001332posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333{
Mark Hammondef8b6542001-05-13 08:04:26 +00001334 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001335}
1336
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001337
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001338PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001339"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001340Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001341
Barry Warsaw53699e91996-12-10 23:23:01 +00001342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001343posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001344{
Mark Hammondef8b6542001-05-13 08:04:26 +00001345 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001346}
1347
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001348
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001349#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001350PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001351"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001352Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001353
Barry Warsaw53699e91996-12-10 23:23:01 +00001354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001355posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001356{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001357 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001358 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001359 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001360 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001361 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001362 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001363 Py_END_ALLOW_THREADS
1364 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001366#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001367
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001368
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001369PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001370"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001371Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001372
Barry Warsaw53699e91996-12-10 23:23:01 +00001373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001374posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001375{
1376 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001377 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001378 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001379 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001380 if (i < 0)
1381 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001382 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001383}
1384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001385
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001386PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001387"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001388Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001389
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001390PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001391"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001392Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001393
Barry Warsaw53699e91996-12-10 23:23:01 +00001394static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001395posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001396{
Mark Hammondef8b6542001-05-13 08:04:26 +00001397 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001398}
1399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001400
Guido van Rossumb6775db1994-08-01 11:34:53 +00001401#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001402PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001403"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001404Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001405
Barry Warsaw53699e91996-12-10 23:23:01 +00001406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001407posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001408{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001409 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001410 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001411 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001412 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001413 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001414 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001415 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001416 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001417 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001418 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001419 u.sysname,
1420 u.nodename,
1421 u.release,
1422 u.version,
1423 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001424}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001425#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001426
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001427
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001428PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001429"utime(path, (atime, utime))\n\
1430utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001431Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001432second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001433
Barry Warsaw53699e91996-12-10 23:23:01 +00001434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001435posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001436{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001437 char *path;
Guido van Rossumf8803dd1995-01-26 00:37:45 +00001438 long atime, mtime;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001439 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001440 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001441
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001442/* XXX should define struct utimbuf instead, above */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001443#ifdef HAVE_UTIME_H
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001444 struct utimbuf buf;
1445#define ATIME buf.actime
1446#define MTIME buf.modtime
1447#define UTIME_ARG &buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001448#else /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001449 time_t buf[2];
1450#define ATIME buf[0]
1451#define MTIME buf[1]
1452#define UTIME_ARG buf
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001453#endif /* HAVE_UTIME_H */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001454
Barry Warsaw3cef8562000-05-01 16:17:24 +00001455 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001456 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001457 if (arg == Py_None) {
1458 /* optional time values not given */
1459 Py_BEGIN_ALLOW_THREADS
1460 res = utime(path, NULL);
1461 Py_END_ALLOW_THREADS
1462 }
1463 else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1464 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001465 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001466 return NULL;
1467 }
1468 else {
1469 ATIME = atime;
1470 MTIME = mtime;
1471 Py_BEGIN_ALLOW_THREADS
1472 res = utime(path, UTIME_ARG);
1473 Py_END_ALLOW_THREADS
1474 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001475 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001476 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001477 Py_INCREF(Py_None);
1478 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001479#undef UTIME_ARG
1480#undef ATIME
1481#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001482}
1483
Guido van Rossum85e3b011991-06-03 12:42:10 +00001484
Guido van Rossum3b066191991-06-04 19:40:25 +00001485/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001486
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001487PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001488"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001489Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001490
Barry Warsaw53699e91996-12-10 23:23:01 +00001491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001492posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001493{
1494 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001495 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001496 return NULL;
1497 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001498 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001499}
1500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001501
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001502#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001503PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001504"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001505Execute an executable path with arguments, replacing current process.\n\
1506\n\
1507 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001508 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001509
Barry Warsaw53699e91996-12-10 23:23:01 +00001510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001511posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001512{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001513 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001514 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001515 char **argvlist;
1516 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001517 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001518
Guido van Rossum89b33251993-10-22 14:26:06 +00001519 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001520 argv is a list or tuple of strings. */
1521
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001522 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001523 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001524 if (PyList_Check(argv)) {
1525 argc = PyList_Size(argv);
1526 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001527 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001528 else if (PyTuple_Check(argv)) {
1529 argc = PyTuple_Size(argv);
1530 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001531 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001532 else {
Fred Drake661ea262000-10-24 19:57:45 +00001533 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001534 return NULL;
1535 }
1536
1537 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001538 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001539 return NULL;
1540 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001541
Barry Warsaw53699e91996-12-10 23:23:01 +00001542 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001543 if (argvlist == NULL)
1544 return NULL;
1545 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001546 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1547 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001548 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001549 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001550 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001551
Guido van Rossum85e3b011991-06-03 12:42:10 +00001552 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001553 }
1554 argvlist[argc] = NULL;
1555
Guido van Rossumb6775db1994-08-01 11:34:53 +00001556#ifdef BAD_EXEC_PROTOTYPES
1557 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001558#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001559 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001560#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001561
Guido van Rossum85e3b011991-06-03 12:42:10 +00001562 /* If we get here it's definitely an error */
1563
Barry Warsaw53699e91996-12-10 23:23:01 +00001564 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001565 return posix_error();
1566}
1567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001568
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001569PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001570"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001571Execute a path with arguments and environment, replacing current process.\n\
1572\n\
1573 path: path of executable file\n\
1574 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001575 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001576
Barry Warsaw53699e91996-12-10 23:23:01 +00001577static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001578posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001579{
1580 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001581 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001582 char **argvlist;
1583 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001584 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001585 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001586 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001587
1588 /* execve has three arguments: (path, argv, env), where
1589 argv is a list or tuple of strings and env is a dictionary
1590 like posix.environ. */
1591
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001592 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001593 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001594 if (PyList_Check(argv)) {
1595 argc = PyList_Size(argv);
1596 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001597 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001598 else if (PyTuple_Check(argv)) {
1599 argc = PyTuple_Size(argv);
1600 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 }
1602 else {
Fred Drake661ea262000-10-24 19:57:45 +00001603 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001604 return NULL;
1605 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001606 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001607 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001608 return NULL;
1609 }
1610
Guido van Rossum50422b42000-04-26 20:34:28 +00001611 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001612 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001613 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001614 return NULL;
1615 }
1616
Barry Warsaw53699e91996-12-10 23:23:01 +00001617 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001618 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001619 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001620 return NULL;
1621 }
1622 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001623 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001624 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001625 &argvlist[i]))
1626 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001627 goto fail_1;
1628 }
1629 }
1630 argvlist[argc] = NULL;
1631
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001632 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001633 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001634 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001635 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001636 goto fail_1;
1637 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001638 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001639 keys = PyMapping_Keys(env);
1640 vals = PyMapping_Values(env);
1641 if (!keys || !vals)
1642 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001643
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001644 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001645 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001646 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001647
1648 key = PyList_GetItem(keys, pos);
1649 val = PyList_GetItem(vals, pos);
1650 if (!key || !val)
1651 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001652
Fred Drake661ea262000-10-24 19:57:45 +00001653 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1654 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001655 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001656 goto fail_2;
1657 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001658
1659#if defined(PYOS_OS2)
1660 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1661 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1662#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001663 len = PyString_Size(key) + PyString_Size(val) + 2;
1664 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001665 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001666 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001667 goto fail_2;
1668 }
Tim Petersc8996f52001-12-03 20:41:00 +00001669 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001670 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001671#if defined(PYOS_OS2)
1672 }
1673#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001674 }
1675 envlist[envc] = 0;
1676
Guido van Rossumb6775db1994-08-01 11:34:53 +00001677
1678#ifdef BAD_EXEC_PROTOTYPES
1679 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001680#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001681 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001682#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001683
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001684 /* If we get here it's definitely an error */
1685
1686 (void) posix_error();
1687
1688 fail_2:
1689 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001690 PyMem_DEL(envlist[envc]);
1691 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001692 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001693 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001694 Py_XDECREF(vals);
1695 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001696 return NULL;
1697}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001698#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001700
Guido van Rossuma1065681999-01-25 23:20:23 +00001701#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001702PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001703"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001704Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001705\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001706 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001707 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001708 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001709
1710static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001711posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001712{
1713 char *path;
1714 PyObject *argv;
1715 char **argvlist;
1716 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001717 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001718 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001719
1720 /* spawnv has three arguments: (mode, path, argv), where
1721 argv is a list or tuple of strings. */
1722
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001723 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001724 return NULL;
1725 if (PyList_Check(argv)) {
1726 argc = PyList_Size(argv);
1727 getitem = PyList_GetItem;
1728 }
1729 else if (PyTuple_Check(argv)) {
1730 argc = PyTuple_Size(argv);
1731 getitem = PyTuple_GetItem;
1732 }
1733 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001734 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001735 return NULL;
1736 }
1737
1738 argvlist = PyMem_NEW(char *, argc+1);
1739 if (argvlist == NULL)
1740 return NULL;
1741 for (i = 0; i < argc; i++) {
1742 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1743 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001744 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001745 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001746 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001747 }
1748 }
1749 argvlist[argc] = NULL;
1750
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001751#if defined(PYOS_OS2) && defined(PYCC_GCC)
1752 Py_BEGIN_ALLOW_THREADS
1753 spawnval = spawnv(mode, path, argvlist);
1754 Py_END_ALLOW_THREADS
1755#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001756 if (mode == _OLD_P_OVERLAY)
1757 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001758
Tim Peters25059d32001-12-07 20:35:43 +00001759 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001760 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001761 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001762#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001763
Guido van Rossuma1065681999-01-25 23:20:23 +00001764 PyMem_DEL(argvlist);
1765
Fred Drake699f3522000-06-29 21:12:41 +00001766 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001767 return posix_error();
1768 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001769#if SIZEOF_LONG == SIZEOF_VOID_P
1770 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001771#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001772 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001773#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001774}
1775
1776
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001777PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001778"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001779Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001780\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001781 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001782 path: path of executable file\n\
1783 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001784 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001785
1786static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001787posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001788{
1789 char *path;
1790 PyObject *argv, *env;
1791 char **argvlist;
1792 char **envlist;
1793 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1794 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001795 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001796 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001797
1798 /* spawnve has four arguments: (mode, path, argv, env), where
1799 argv is a list or tuple of strings and env is a dictionary
1800 like posix.environ. */
1801
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001802 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001803 return NULL;
1804 if (PyList_Check(argv)) {
1805 argc = PyList_Size(argv);
1806 getitem = PyList_GetItem;
1807 }
1808 else if (PyTuple_Check(argv)) {
1809 argc = PyTuple_Size(argv);
1810 getitem = PyTuple_GetItem;
1811 }
1812 else {
Fred Drake661ea262000-10-24 19:57:45 +00001813 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001814 return NULL;
1815 }
1816 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001817 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001818 return NULL;
1819 }
1820
1821 argvlist = PyMem_NEW(char *, argc+1);
1822 if (argvlist == NULL) {
1823 PyErr_NoMemory();
1824 return NULL;
1825 }
1826 for (i = 0; i < argc; i++) {
1827 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001828 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001829 &argvlist[i]))
1830 {
1831 goto fail_1;
1832 }
1833 }
1834 argvlist[argc] = NULL;
1835
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001836 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001837 envlist = PyMem_NEW(char *, i + 1);
1838 if (envlist == NULL) {
1839 PyErr_NoMemory();
1840 goto fail_1;
1841 }
1842 envc = 0;
1843 keys = PyMapping_Keys(env);
1844 vals = PyMapping_Values(env);
1845 if (!keys || !vals)
1846 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001847
Guido van Rossuma1065681999-01-25 23:20:23 +00001848 for (pos = 0; pos < i; pos++) {
1849 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001850 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001851
1852 key = PyList_GetItem(keys, pos);
1853 val = PyList_GetItem(vals, pos);
1854 if (!key || !val)
1855 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001856
Fred Drake661ea262000-10-24 19:57:45 +00001857 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1858 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001859 {
1860 goto fail_2;
1861 }
Tim Petersc8996f52001-12-03 20:41:00 +00001862 len = PyString_Size(key) + PyString_Size(val) + 2;
1863 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001864 if (p == NULL) {
1865 PyErr_NoMemory();
1866 goto fail_2;
1867 }
Tim Petersc8996f52001-12-03 20:41:00 +00001868 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001869 envlist[envc++] = p;
1870 }
1871 envlist[envc] = 0;
1872
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001873#if defined(PYOS_OS2) && defined(PYCC_GCC)
1874 Py_BEGIN_ALLOW_THREADS
1875 spawnval = spawnve(mode, path, argvlist, envlist);
1876 Py_END_ALLOW_THREADS
1877#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001878 if (mode == _OLD_P_OVERLAY)
1879 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001880
1881 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001882 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001883 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001884#endif
Tim Peters25059d32001-12-07 20:35:43 +00001885
Fred Drake699f3522000-06-29 21:12:41 +00001886 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001887 (void) posix_error();
1888 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001889#if SIZEOF_LONG == SIZEOF_VOID_P
1890 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001891#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001892 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001893#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001894
1895 fail_2:
1896 while (--envc >= 0)
1897 PyMem_DEL(envlist[envc]);
1898 PyMem_DEL(envlist);
1899 fail_1:
1900 PyMem_DEL(argvlist);
1901 Py_XDECREF(vals);
1902 Py_XDECREF(keys);
1903 return res;
1904}
1905#endif /* HAVE_SPAWNV */
1906
1907
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001908#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001909PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001910"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001911Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1912\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001913Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001914
1915static PyObject *
1916posix_fork1(self, args)
1917 PyObject *self;
1918 PyObject *args;
1919{
1920 int pid;
1921 if (!PyArg_ParseTuple(args, ":fork1"))
1922 return NULL;
1923 pid = fork1();
1924 if (pid == -1)
1925 return posix_error();
1926 PyOS_AfterFork();
1927 return PyInt_FromLong((long)pid);
1928}
1929#endif
1930
1931
Guido van Rossumad0ee831995-03-01 10:34:45 +00001932#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001933PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001934"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001935Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001936Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001937
Barry Warsaw53699e91996-12-10 23:23:01 +00001938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001939posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001940{
1941 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001942 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001943 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001944 pid = fork();
1945 if (pid == -1)
1946 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001947 if (pid == 0)
1948 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001949 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001950}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001951#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001952
Fred Drake8cef4cf2000-06-28 16:40:38 +00001953#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1954#ifdef HAVE_PTY_H
1955#include <pty.h>
1956#else
1957#ifdef HAVE_LIBUTIL_H
1958#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001959#endif /* HAVE_LIBUTIL_H */
1960#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001961#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001962
Thomas Wouters70c21a12000-07-14 14:28:33 +00001963#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001964PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001965"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001966Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001967
1968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001969posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001970{
1971 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001972#ifndef HAVE_OPENPTY
1973 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001974#endif
1975
Fred Drake8cef4cf2000-06-28 16:40:38 +00001976 if (!PyArg_ParseTuple(args, ":openpty"))
1977 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001978
1979#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001980 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1981 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00001982#else
1983 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1984 if (slave_name == NULL)
1985 return posix_error();
1986
1987 slave_fd = open(slave_name, O_RDWR);
1988 if (slave_fd < 0)
1989 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00001990#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001991
Fred Drake8cef4cf2000-06-28 16:40:38 +00001992 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00001993
Fred Drake8cef4cf2000-06-28 16:40:38 +00001994}
Thomas Wouters70c21a12000-07-14 14:28:33 +00001995#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001996
1997#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001998PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001999"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002000Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2001Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002002To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002003
2004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002005posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002006{
2007 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002008
Fred Drake8cef4cf2000-06-28 16:40:38 +00002009 if (!PyArg_ParseTuple(args, ":forkpty"))
2010 return NULL;
2011 pid = forkpty(&master_fd, NULL, NULL, NULL);
2012 if (pid == -1)
2013 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002014 if (pid == 0)
2015 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002016 return Py_BuildValue("(ii)", pid, master_fd);
2017}
2018#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002019
Guido van Rossumad0ee831995-03-01 10:34:45 +00002020#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002021PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002022"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002023Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002024
Barry Warsaw53699e91996-12-10 23:23:01 +00002025static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002026posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002027{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002028 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002029 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002030 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002031}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002032#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002034
Guido van Rossumad0ee831995-03-01 10:34:45 +00002035#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002036PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002037"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002038Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002039
Barry Warsaw53699e91996-12-10 23:23:01 +00002040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002041posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002042{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002043 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002044 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002045 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002046}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002047#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002049
Guido van Rossumad0ee831995-03-01 10:34:45 +00002050#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002051PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002052"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002053Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002054
Barry Warsaw53699e91996-12-10 23:23:01 +00002055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002056posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002057{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002058 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002059 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002060 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002061}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002062#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002064
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002065PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002066"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002067Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068
Barry Warsaw53699e91996-12-10 23:23:01 +00002069static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002070posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002071{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002072 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002073 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002074 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002075}
2076
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002077
Fred Drakec9680921999-12-13 16:37:25 +00002078#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002079PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002080"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002081Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002082
2083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002084posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002085{
2086 PyObject *result = NULL;
2087
2088 if (PyArg_ParseTuple(args, ":getgroups")) {
2089#ifdef NGROUPS_MAX
2090#define MAX_GROUPS NGROUPS_MAX
2091#else
2092 /* defined to be 16 on Solaris7, so this should be a small number */
2093#define MAX_GROUPS 64
2094#endif
2095 gid_t grouplist[MAX_GROUPS];
2096 int n;
2097
2098 n = getgroups(MAX_GROUPS, grouplist);
2099 if (n < 0)
2100 posix_error();
2101 else {
2102 result = PyList_New(n);
2103 if (result != NULL) {
2104 PyObject *o;
2105 int i;
2106 for (i = 0; i < n; ++i) {
2107 o = PyInt_FromLong((long)grouplist[i]);
2108 if (o == NULL) {
2109 Py_DECREF(result);
2110 result = NULL;
2111 break;
2112 }
2113 PyList_SET_ITEM(result, i, o);
2114 }
2115 }
2116 }
2117 }
2118 return result;
2119}
2120#endif
2121
Martin v. Löwis606edc12002-06-13 21:09:11 +00002122#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002123PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002124"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002125Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002126
2127static PyObject *
2128posix_getpgid(PyObject *self, PyObject *args)
2129{
2130 int pid, pgid;
2131 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2132 return NULL;
2133 pgid = getpgid(pid);
2134 if (pgid < 0)
2135 return posix_error();
2136 return PyInt_FromLong((long)pgid);
2137}
2138#endif /* HAVE_GETPGID */
2139
2140
Guido van Rossumb6775db1994-08-01 11:34:53 +00002141#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002143"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002144Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002145
Barry Warsaw53699e91996-12-10 23:23:01 +00002146static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002147posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002148{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002149 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002150 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002151#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002152 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002153#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002154 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002155#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002156}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002157#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002159
Guido van Rossumb6775db1994-08-01 11:34:53 +00002160#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002161PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002162"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002163Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002164
Barry Warsaw53699e91996-12-10 23:23:01 +00002165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002166posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002167{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002168 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002169 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002170#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002171 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002172#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002173 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002174#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002175 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002176 Py_INCREF(Py_None);
2177 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002178}
2179
Guido van Rossumb6775db1994-08-01 11:34:53 +00002180#endif /* HAVE_SETPGRP */
2181
Guido van Rossumad0ee831995-03-01 10:34:45 +00002182#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002183PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002184"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002185Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002186
Barry Warsaw53699e91996-12-10 23:23:01 +00002187static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002188posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002189{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002190 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002191 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002192 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002193}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002194#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002195
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002196
Fred Drake12c6e2d1999-12-14 21:25:03 +00002197#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002198PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002199"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002200Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002201
2202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002203posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002204{
2205 PyObject *result = NULL;
2206
2207 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002208 char *name;
2209 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002210
Fred Drakea30680b2000-12-06 21:24:28 +00002211 errno = 0;
2212 name = getlogin();
2213 if (name == NULL) {
2214 if (errno)
2215 posix_error();
2216 else
2217 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002218 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002219 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002220 else
2221 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002222 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002223 }
2224 return result;
2225}
2226#endif
2227
Guido van Rossumad0ee831995-03-01 10:34:45 +00002228#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002229PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002230"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002231Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002232
Barry Warsaw53699e91996-12-10 23:23:01 +00002233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002234posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002235{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002236 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002237 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002238 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002239}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002240#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002241
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002242
Guido van Rossumad0ee831995-03-01 10:34:45 +00002243#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002244PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002245"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002246Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002247
Barry Warsaw53699e91996-12-10 23:23:01 +00002248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002249posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002250{
2251 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002252 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002253 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002254#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002255 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2256 APIRET rc;
2257 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002258 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002259
2260 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2261 APIRET rc;
2262 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002263 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002264
2265 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002266 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002267#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002268 if (kill(pid, sig) == -1)
2269 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002270#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002271 Py_INCREF(Py_None);
2272 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002273}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002274#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002275
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002276#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002277PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002278"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002279Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002280
2281static PyObject *
2282posix_killpg(PyObject *self, PyObject *args)
2283{
2284 int pgid, sig;
2285 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2286 return NULL;
2287 if (killpg(pgid, sig) == -1)
2288 return posix_error();
2289 Py_INCREF(Py_None);
2290 return Py_None;
2291}
2292#endif
2293
Guido van Rossumc0125471996-06-28 18:55:32 +00002294#ifdef HAVE_PLOCK
2295
2296#ifdef HAVE_SYS_LOCK_H
2297#include <sys/lock.h>
2298#endif
2299
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002300PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002301"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002302Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002303
Barry Warsaw53699e91996-12-10 23:23:01 +00002304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002305posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002306{
2307 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002308 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002309 return NULL;
2310 if (plock(op) == -1)
2311 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002312 Py_INCREF(Py_None);
2313 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002314}
2315#endif
2316
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002317
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002318#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002319PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002320"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002321Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002322
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002323#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002324#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002325static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002326async_system(const char *command)
2327{
2328 char *p, errormsg[256], args[1024];
2329 RESULTCODES rcodes;
2330 APIRET rc;
2331 char *shell = getenv("COMSPEC");
2332 if (!shell)
2333 shell = "cmd";
2334
2335 strcpy(args, shell);
2336 p = &args[ strlen(args)+1 ];
2337 strcpy(p, "/c ");
2338 strcat(p, command);
2339 p += strlen(p) + 1;
2340 *p = '\0';
2341
2342 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002343 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002344 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002345 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002346 &rcodes, shell);
2347 return rc;
2348}
2349
Guido van Rossumd48f2521997-12-05 22:19:34 +00002350static FILE *
2351popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002352{
2353 HFILE rhan, whan;
2354 FILE *retfd = NULL;
2355 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2356
Guido van Rossumd48f2521997-12-05 22:19:34 +00002357 if (rc != NO_ERROR) {
2358 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002359 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002360 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002361
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002362 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2363 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002364
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002365 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2366 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002367
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002368 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2369 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002370
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002371 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002372 }
2373
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002374 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2375 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002376
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002377 if (rc == NO_ERROR)
2378 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2379
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002380 close(oldfd); /* And Close Saved STDOUT Handle */
2381 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002382
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002383 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2384 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002385
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002386 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2387 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002388
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002389 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2390 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002391
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002392 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002393 }
2394
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002395 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2396 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002397
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002398 if (rc == NO_ERROR)
2399 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2400
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002401 close(oldfd); /* And Close Saved STDIN Handle */
2402 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002403
Guido van Rossumd48f2521997-12-05 22:19:34 +00002404 } else {
2405 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002406 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002407 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002408}
2409
2410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002411posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002412{
2413 char *name;
2414 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002415 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002416 FILE *fp;
2417 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002418 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002419 return NULL;
2420 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002421 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002422 Py_END_ALLOW_THREADS
2423 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002424 return os2_error(err);
2425
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002426 f = PyFile_FromFile(fp, name, mode, fclose);
2427 if (f != NULL)
2428 PyFile_SetBufSize(f, bufsize);
2429 return f;
2430}
2431
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002432#elif defined(PYCC_GCC)
2433
2434/* standard posix version of popen() support */
2435static PyObject *
2436posix_popen(PyObject *self, PyObject *args)
2437{
2438 char *name;
2439 char *mode = "r";
2440 int bufsize = -1;
2441 FILE *fp;
2442 PyObject *f;
2443 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2444 return NULL;
2445 Py_BEGIN_ALLOW_THREADS
2446 fp = popen(name, mode);
2447 Py_END_ALLOW_THREADS
2448 if (fp == NULL)
2449 return posix_error();
2450 f = PyFile_FromFile(fp, name, mode, pclose);
2451 if (f != NULL)
2452 PyFile_SetBufSize(f, bufsize);
2453 return f;
2454}
2455
2456/* fork() under OS/2 has lots'o'warts
2457 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2458 * most of this code is a ripoff of the win32 code, but using the
2459 * capabilities of EMX's C library routines
2460 */
2461
2462/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2463#define POPEN_1 1
2464#define POPEN_2 2
2465#define POPEN_3 3
2466#define POPEN_4 4
2467
2468static PyObject *_PyPopen(char *, int, int, int);
2469static int _PyPclose(FILE *file);
2470
2471/*
2472 * Internal dictionary mapping popen* file pointers to process handles,
2473 * for use when retrieving the process exit code. See _PyPclose() below
2474 * for more information on this dictionary's use.
2475 */
2476static PyObject *_PyPopenProcs = NULL;
2477
2478/* os2emx version of popen2()
2479 *
2480 * The result of this function is a pipe (file) connected to the
2481 * process's stdin, and a pipe connected to the process's stdout.
2482 */
2483
2484static PyObject *
2485os2emx_popen2(PyObject *self, PyObject *args)
2486{
2487 PyObject *f;
2488 int tm=0;
2489
2490 char *cmdstring;
2491 char *mode = "t";
2492 int bufsize = -1;
2493 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2494 return NULL;
2495
2496 if (*mode == 't')
2497 tm = O_TEXT;
2498 else if (*mode != 'b') {
2499 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2500 return NULL;
2501 } else
2502 tm = O_BINARY;
2503
2504 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2505
2506 return f;
2507}
2508
2509/*
2510 * Variation on os2emx.popen2
2511 *
2512 * The result of this function is 3 pipes - the process's stdin,
2513 * stdout and stderr
2514 */
2515
2516static PyObject *
2517os2emx_popen3(PyObject *self, PyObject *args)
2518{
2519 PyObject *f;
2520 int tm = 0;
2521
2522 char *cmdstring;
2523 char *mode = "t";
2524 int bufsize = -1;
2525 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2526 return NULL;
2527
2528 if (*mode == 't')
2529 tm = O_TEXT;
2530 else if (*mode != 'b') {
2531 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2532 return NULL;
2533 } else
2534 tm = O_BINARY;
2535
2536 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2537
2538 return f;
2539}
2540
2541/*
2542 * Variation on os2emx.popen2
2543 *
2544 * The result of this function is 2 pipes - the processes stdin,
2545 * and stdout+stderr combined as a single pipe.
2546 */
2547
2548static PyObject *
2549os2emx_popen4(PyObject *self, PyObject *args)
2550{
2551 PyObject *f;
2552 int tm = 0;
2553
2554 char *cmdstring;
2555 char *mode = "t";
2556 int bufsize = -1;
2557 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2558 return NULL;
2559
2560 if (*mode == 't')
2561 tm = O_TEXT;
2562 else if (*mode != 'b') {
2563 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2564 return NULL;
2565 } else
2566 tm = O_BINARY;
2567
2568 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2569
2570 return f;
2571}
2572
2573/* a couple of structures for convenient handling of multiple
2574 * file handles and pipes
2575 */
2576struct file_ref
2577{
2578 int handle;
2579 int flags;
2580};
2581
2582struct pipe_ref
2583{
2584 int rd;
2585 int wr;
2586};
2587
2588/* The following code is derived from the win32 code */
2589
2590static PyObject *
2591_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2592{
2593 struct file_ref stdio[3];
2594 struct pipe_ref p_fd[3];
2595 FILE *p_s[3];
2596 int file_count, i, pipe_err, pipe_pid;
2597 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2598 PyObject *f, *p_f[3];
2599
2600 /* file modes for subsequent fdopen's on pipe handles */
2601 if (mode == O_TEXT)
2602 {
2603 rd_mode = "rt";
2604 wr_mode = "wt";
2605 }
2606 else
2607 {
2608 rd_mode = "rb";
2609 wr_mode = "wb";
2610 }
2611
2612 /* prepare shell references */
2613 if ((shell = getenv("EMXSHELL")) == NULL)
2614 if ((shell = getenv("COMSPEC")) == NULL)
2615 {
2616 errno = ENOENT;
2617 return posix_error();
2618 }
2619
2620 sh_name = _getname(shell);
2621 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2622 opt = "/c";
2623 else
2624 opt = "-c";
2625
2626 /* save current stdio fds + their flags, and set not inheritable */
2627 i = pipe_err = 0;
2628 while (pipe_err >= 0 && i < 3)
2629 {
2630 pipe_err = stdio[i].handle = dup(i);
2631 stdio[i].flags = fcntl(i, F_GETFD, 0);
2632 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2633 i++;
2634 }
2635 if (pipe_err < 0)
2636 {
2637 /* didn't get them all saved - clean up and bail out */
2638 int saved_err = errno;
2639 while (i-- > 0)
2640 {
2641 close(stdio[i].handle);
2642 }
2643 errno = saved_err;
2644 return posix_error();
2645 }
2646
2647 /* create pipe ends */
2648 file_count = 2;
2649 if (n == POPEN_3)
2650 file_count = 3;
2651 i = pipe_err = 0;
2652 while ((pipe_err == 0) && (i < file_count))
2653 pipe_err = pipe((int *)&p_fd[i++]);
2654 if (pipe_err < 0)
2655 {
2656 /* didn't get them all made - clean up and bail out */
2657 while (i-- > 0)
2658 {
2659 close(p_fd[i].wr);
2660 close(p_fd[i].rd);
2661 }
2662 errno = EPIPE;
2663 return posix_error();
2664 }
2665
2666 /* change the actual standard IO streams over temporarily,
2667 * making the retained pipe ends non-inheritable
2668 */
2669 pipe_err = 0;
2670
2671 /* - stdin */
2672 if (dup2(p_fd[0].rd, 0) == 0)
2673 {
2674 close(p_fd[0].rd);
2675 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2676 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2677 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2678 {
2679 close(p_fd[0].wr);
2680 pipe_err = -1;
2681 }
2682 }
2683 else
2684 {
2685 pipe_err = -1;
2686 }
2687
2688 /* - stdout */
2689 if (pipe_err == 0)
2690 {
2691 if (dup2(p_fd[1].wr, 1) == 1)
2692 {
2693 close(p_fd[1].wr);
2694 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2695 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2696 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2697 {
2698 close(p_fd[1].rd);
2699 pipe_err = -1;
2700 }
2701 }
2702 else
2703 {
2704 pipe_err = -1;
2705 }
2706 }
2707
2708 /* - stderr, as required */
2709 if (pipe_err == 0)
2710 switch (n)
2711 {
2712 case POPEN_3:
2713 {
2714 if (dup2(p_fd[2].wr, 2) == 2)
2715 {
2716 close(p_fd[2].wr);
2717 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2718 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2719 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2720 {
2721 close(p_fd[2].rd);
2722 pipe_err = -1;
2723 }
2724 }
2725 else
2726 {
2727 pipe_err = -1;
2728 }
2729 break;
2730 }
2731
2732 case POPEN_4:
2733 {
2734 if (dup2(1, 2) != 2)
2735 {
2736 pipe_err = -1;
2737 }
2738 break;
2739 }
2740 }
2741
2742 /* spawn the child process */
2743 if (pipe_err == 0)
2744 {
2745 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2746 if (pipe_pid == -1)
2747 {
2748 pipe_err = -1;
2749 }
2750 else
2751 {
2752 /* save the PID into the FILE structure
2753 * NOTE: this implementation doesn't actually
2754 * take advantage of this, but do it for
2755 * completeness - AIM Apr01
2756 */
2757 for (i = 0; i < file_count; i++)
2758 p_s[i]->_pid = pipe_pid;
2759 }
2760 }
2761
2762 /* reset standard IO to normal */
2763 for (i = 0; i < 3; i++)
2764 {
2765 dup2(stdio[i].handle, i);
2766 fcntl(i, F_SETFD, stdio[i].flags);
2767 close(stdio[i].handle);
2768 }
2769
2770 /* if any remnant problems, clean up and bail out */
2771 if (pipe_err < 0)
2772 {
2773 for (i = 0; i < 3; i++)
2774 {
2775 close(p_fd[i].rd);
2776 close(p_fd[i].wr);
2777 }
2778 errno = EPIPE;
2779 return posix_error_with_filename(cmdstring);
2780 }
2781
2782 /* build tuple of file objects to return */
2783 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2784 PyFile_SetBufSize(p_f[0], bufsize);
2785 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2786 PyFile_SetBufSize(p_f[1], bufsize);
2787 if (n == POPEN_3)
2788 {
2789 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2790 PyFile_SetBufSize(p_f[0], bufsize);
2791 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2792 }
2793 else
2794 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2795
2796 /*
2797 * Insert the files we've created into the process dictionary
2798 * all referencing the list with the process handle and the
2799 * initial number of files (see description below in _PyPclose).
2800 * Since if _PyPclose later tried to wait on a process when all
2801 * handles weren't closed, it could create a deadlock with the
2802 * child, we spend some energy here to try to ensure that we
2803 * either insert all file handles into the dictionary or none
2804 * at all. It's a little clumsy with the various popen modes
2805 * and variable number of files involved.
2806 */
2807 if (!_PyPopenProcs)
2808 {
2809 _PyPopenProcs = PyDict_New();
2810 }
2811
2812 if (_PyPopenProcs)
2813 {
2814 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2815 int ins_rc[3];
2816
2817 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2818 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2819
2820 procObj = PyList_New(2);
2821 pidObj = PyInt_FromLong((long) pipe_pid);
2822 intObj = PyInt_FromLong((long) file_count);
2823
2824 if (procObj && pidObj && intObj)
2825 {
2826 PyList_SetItem(procObj, 0, pidObj);
2827 PyList_SetItem(procObj, 1, intObj);
2828
2829 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2830 if (fileObj[0])
2831 {
2832 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2833 fileObj[0],
2834 procObj);
2835 }
2836 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2837 if (fileObj[1])
2838 {
2839 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2840 fileObj[1],
2841 procObj);
2842 }
2843 if (file_count >= 3)
2844 {
2845 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2846 if (fileObj[2])
2847 {
2848 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2849 fileObj[2],
2850 procObj);
2851 }
2852 }
2853
2854 if (ins_rc[0] < 0 || !fileObj[0] ||
2855 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2856 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2857 {
2858 /* Something failed - remove any dictionary
2859 * entries that did make it.
2860 */
2861 if (!ins_rc[0] && fileObj[0])
2862 {
2863 PyDict_DelItem(_PyPopenProcs,
2864 fileObj[0]);
2865 }
2866 if (!ins_rc[1] && fileObj[1])
2867 {
2868 PyDict_DelItem(_PyPopenProcs,
2869 fileObj[1]);
2870 }
2871 if (!ins_rc[2] && fileObj[2])
2872 {
2873 PyDict_DelItem(_PyPopenProcs,
2874 fileObj[2]);
2875 }
2876 }
2877 }
2878
2879 /*
2880 * Clean up our localized references for the dictionary keys
2881 * and value since PyDict_SetItem will Py_INCREF any copies
2882 * that got placed in the dictionary.
2883 */
2884 Py_XDECREF(procObj);
2885 Py_XDECREF(fileObj[0]);
2886 Py_XDECREF(fileObj[1]);
2887 Py_XDECREF(fileObj[2]);
2888 }
2889
2890 /* Child is launched. */
2891 return f;
2892}
2893
2894/*
2895 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2896 * exit code for the child process and return as a result of the close.
2897 *
2898 * This function uses the _PyPopenProcs dictionary in order to map the
2899 * input file pointer to information about the process that was
2900 * originally created by the popen* call that created the file pointer.
2901 * The dictionary uses the file pointer as a key (with one entry
2902 * inserted for each file returned by the original popen* call) and a
2903 * single list object as the value for all files from a single call.
2904 * The list object contains the Win32 process handle at [0], and a file
2905 * count at [1], which is initialized to the total number of file
2906 * handles using that list.
2907 *
2908 * This function closes whichever handle it is passed, and decrements
2909 * the file count in the dictionary for the process handle pointed to
2910 * by this file. On the last close (when the file count reaches zero),
2911 * this function will wait for the child process and then return its
2912 * exit code as the result of the close() operation. This permits the
2913 * files to be closed in any order - it is always the close() of the
2914 * final handle that will return the exit code.
2915 */
2916
2917 /* RED_FLAG 31-Aug-2000 Tim
2918 * This is always called (today!) between a pair of
2919 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2920 * macros. So the thread running this has no valid thread state, as
2921 * far as Python is concerned. However, this calls some Python API
2922 * functions that cannot be called safely without a valid thread
2923 * state, in particular PyDict_GetItem.
2924 * As a temporary hack (although it may last for years ...), we
2925 * *rely* on not having a valid thread state in this function, in
2926 * order to create our own "from scratch".
2927 * This will deadlock if _PyPclose is ever called by a thread
2928 * holding the global lock.
2929 * (The OS/2 EMX thread support appears to cover the case where the
2930 * lock is already held - AIM Apr01)
2931 */
2932
2933static int _PyPclose(FILE *file)
2934{
2935 int result;
2936 int exit_code;
2937 int pipe_pid;
2938 PyObject *procObj, *pidObj, *intObj, *fileObj;
2939 int file_count;
2940#ifdef WITH_THREAD
2941 PyInterpreterState* pInterpreterState;
2942 PyThreadState* pThreadState;
2943#endif
2944
2945 /* Close the file handle first, to ensure it can't block the
2946 * child from exiting if it's the last handle.
2947 */
2948 result = fclose(file);
2949
2950#ifdef WITH_THREAD
2951 /* Bootstrap a valid thread state into existence. */
2952 pInterpreterState = PyInterpreterState_New();
2953 if (!pInterpreterState) {
2954 /* Well, we're hosed now! We don't have a thread
2955 * state, so can't call a nice error routine, or raise
2956 * an exception. Just die.
2957 */
2958 Py_FatalError("unable to allocate interpreter state "
2959 "when closing popen object.");
2960 return -1; /* unreachable */
2961 }
2962 pThreadState = PyThreadState_New(pInterpreterState);
2963 if (!pThreadState) {
2964 Py_FatalError("unable to allocate thread state "
2965 "when closing popen object.");
2966 return -1; /* unreachable */
2967 }
2968 /* Grab the global lock. Note that this will deadlock if the
2969 * current thread already has the lock! (see RED_FLAG comments
2970 * before this function)
2971 */
2972 PyEval_RestoreThread(pThreadState);
2973#endif
2974
2975 if (_PyPopenProcs)
2976 {
2977 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2978 (procObj = PyDict_GetItem(_PyPopenProcs,
2979 fileObj)) != NULL &&
2980 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
2981 (intObj = PyList_GetItem(procObj,1)) != NULL)
2982 {
2983 pipe_pid = (int) PyInt_AsLong(pidObj);
2984 file_count = (int) PyInt_AsLong(intObj);
2985
2986 if (file_count > 1)
2987 {
2988 /* Still other files referencing process */
2989 file_count--;
2990 PyList_SetItem(procObj,1,
2991 PyInt_FromLong((long) file_count));
2992 }
2993 else
2994 {
2995 /* Last file for this process */
2996 if (result != EOF &&
2997 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
2998 {
2999 /* extract exit status */
3000 if (WIFEXITED(exit_code))
3001 {
3002 result = WEXITSTATUS(exit_code);
3003 }
3004 else
3005 {
3006 errno = EPIPE;
3007 result = -1;
3008 }
3009 }
3010 else
3011 {
3012 /* Indicate failure - this will cause the file object
3013 * to raise an I/O error and translate the last
3014 * error code from errno. We do have a problem with
3015 * last errors that overlap the normal errno table,
3016 * but that's a consistent problem with the file object.
3017 */
3018 result = -1;
3019 }
3020 }
3021
3022 /* Remove this file pointer from dictionary */
3023 PyDict_DelItem(_PyPopenProcs, fileObj);
3024
3025 if (PyDict_Size(_PyPopenProcs) == 0)
3026 {
3027 Py_DECREF(_PyPopenProcs);
3028 _PyPopenProcs = NULL;
3029 }
3030
3031 } /* if object retrieval ok */
3032
3033 Py_XDECREF(fileObj);
3034 } /* if _PyPopenProcs */
3035
3036#ifdef WITH_THREAD
3037 /* Tear down the thread & interpreter states.
3038 * Note that interpreter state clear & delete functions automatically
3039 * call the thread clear & delete functions, and indeed insist on
3040 * doing that themselves. The lock must be held during the clear, but
3041 * need not be held during the delete.
3042 */
3043 PyInterpreterState_Clear(pInterpreterState);
3044 PyEval_ReleaseThread(pThreadState);
3045 PyInterpreterState_Delete(pInterpreterState);
3046#endif
3047
3048 return result;
3049}
3050
3051#endif /* PYCC_??? */
3052
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003053#elif defined(MS_WIN32)
3054
3055/*
3056 * Portable 'popen' replacement for Win32.
3057 *
3058 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3059 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003060 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003061 */
3062
3063#include <malloc.h>
3064#include <io.h>
3065#include <fcntl.h>
3066
3067/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3068#define POPEN_1 1
3069#define POPEN_2 2
3070#define POPEN_3 3
3071#define POPEN_4 4
3072
3073static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003074static int _PyPclose(FILE *file);
3075
3076/*
3077 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003078 * for use when retrieving the process exit code. See _PyPclose() below
3079 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003080 */
3081static PyObject *_PyPopenProcs = NULL;
3082
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003083
3084/* popen that works from a GUI.
3085 *
3086 * The result of this function is a pipe (file) connected to the
3087 * processes stdin or stdout, depending on the requested mode.
3088 */
3089
3090static PyObject *
3091posix_popen(PyObject *self, PyObject *args)
3092{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003093 PyObject *f, *s;
3094 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003095
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003096 char *cmdstring;
3097 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003098 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003099 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003100 return NULL;
3101
3102 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003103
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003104 if (*mode == 'r')
3105 tm = _O_RDONLY;
3106 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003107 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003108 return NULL;
3109 } else
3110 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003111
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003112 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003113 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003114 return NULL;
3115 }
3116
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003117 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003118 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003119 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003120 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003121 else
3122 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3123
3124 return f;
3125}
3126
3127/* Variation on win32pipe.popen
3128 *
3129 * The result of this function is a pipe (file) connected to the
3130 * process's stdin, and a pipe connected to the process's stdout.
3131 */
3132
3133static PyObject *
3134win32_popen2(PyObject *self, PyObject *args)
3135{
3136 PyObject *f;
3137 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003138
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003139 char *cmdstring;
3140 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003141 int bufsize = -1;
3142 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003143 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003144
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003145 if (*mode == 't')
3146 tm = _O_TEXT;
3147 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003148 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003149 return NULL;
3150 } else
3151 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003152
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003153 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003154 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003155 return NULL;
3156 }
3157
3158 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003159
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003160 return f;
3161}
3162
3163/*
3164 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003165 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003166 * The result of this function is 3 pipes - the process's stdin,
3167 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003168 */
3169
3170static PyObject *
3171win32_popen3(PyObject *self, PyObject *args)
3172{
3173 PyObject *f;
3174 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003175
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003176 char *cmdstring;
3177 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003178 int bufsize = -1;
3179 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003180 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003181
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003182 if (*mode == 't')
3183 tm = _O_TEXT;
3184 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003185 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003186 return NULL;
3187 } else
3188 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003189
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003190 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003191 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003192 return NULL;
3193 }
3194
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003195 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003196
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003197 return f;
3198}
3199
3200/*
3201 * Variation on win32pipe.popen
3202 *
Tim Peters5aa91602002-01-30 05:46:57 +00003203 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003204 * and stdout+stderr combined as a single pipe.
3205 */
3206
3207static PyObject *
3208win32_popen4(PyObject *self, PyObject *args)
3209{
3210 PyObject *f;
3211 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003212
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003213 char *cmdstring;
3214 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003215 int bufsize = -1;
3216 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003217 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003218
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003219 if (*mode == 't')
3220 tm = _O_TEXT;
3221 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003222 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003223 return NULL;
3224 } else
3225 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003226
3227 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003228 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003229 return NULL;
3230 }
3231
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003232 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003233
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003234 return f;
3235}
3236
Mark Hammond08501372001-01-31 07:30:29 +00003237static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003238_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003239 HANDLE hStdin,
3240 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003241 HANDLE hStderr,
3242 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003243{
3244 PROCESS_INFORMATION piProcInfo;
3245 STARTUPINFO siStartInfo;
3246 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003247 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003248 int i;
3249 int x;
3250
3251 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003252 char *comshell;
3253
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003254 s1 = (char *)_alloca(i);
3255 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3256 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003257
3258 /* Explicitly check if we are using COMMAND.COM. If we are
3259 * then use the w9xpopen hack.
3260 */
3261 comshell = s1 + x;
3262 while (comshell >= s1 && *comshell != '\\')
3263 --comshell;
3264 ++comshell;
3265
3266 if (GetVersion() < 0x80000000 &&
3267 _stricmp(comshell, "command.com") != 0) {
3268 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003269 x = i + strlen(s3) + strlen(cmdstring) + 1;
3270 s2 = (char *)_alloca(x);
3271 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003272 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003273 }
3274 else {
3275 /*
Tim Peters402d5982001-08-27 06:37:48 +00003276 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3277 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003278 */
Mark Hammond08501372001-01-31 07:30:29 +00003279 char modulepath[_MAX_PATH];
3280 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003281 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3282 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003283 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003284 x = i+1;
3285 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003286 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003287 strncat(modulepath,
3288 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003289 (sizeof(modulepath)/sizeof(modulepath[0]))
3290 -strlen(modulepath));
3291 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003292 /* Eeek - file-not-found - possibly an embedding
3293 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003294 */
Tim Peters5aa91602002-01-30 05:46:57 +00003295 strncpy(modulepath,
3296 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003297 sizeof(modulepath)/sizeof(modulepath[0]));
3298 if (modulepath[strlen(modulepath)-1] != '\\')
3299 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003300 strncat(modulepath,
3301 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003302 (sizeof(modulepath)/sizeof(modulepath[0]))
3303 -strlen(modulepath));
3304 /* No where else to look - raise an easily identifiable
3305 error, rather than leaving Windows to report
3306 "file not found" - as the user is probably blissfully
3307 unaware this shim EXE is used, and it will confuse them.
3308 (well, it confused me for a while ;-)
3309 */
3310 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003311 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003312 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003313 "for popen to work with your shell "
3314 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003315 szConsoleSpawn);
3316 return FALSE;
3317 }
3318 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003319 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003320 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003321 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003322
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003323 s2 = (char *)_alloca(x);
3324 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003325 /* To maintain correct argument passing semantics,
3326 we pass the command-line as it stands, and allow
3327 quoting to be applied. w9xpopen.exe will then
3328 use its argv vector, and re-quote the necessary
3329 args for the ultimate child process.
3330 */
Tim Peters75cdad52001-11-28 22:07:30 +00003331 PyOS_snprintf(
3332 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003333 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003334 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003335 s1,
3336 s3,
3337 cmdstring);
3338 }
3339 }
3340
3341 /* Could be an else here to try cmd.exe / command.com in the path
3342 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003343 else {
Tim Peters402d5982001-08-27 06:37:48 +00003344 PyErr_SetString(PyExc_RuntimeError,
3345 "Cannot locate a COMSPEC environment variable to "
3346 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003347 return FALSE;
3348 }
Tim Peters5aa91602002-01-30 05:46:57 +00003349
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003350 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3351 siStartInfo.cb = sizeof(STARTUPINFO);
3352 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3353 siStartInfo.hStdInput = hStdin;
3354 siStartInfo.hStdOutput = hStdout;
3355 siStartInfo.hStdError = hStderr;
3356 siStartInfo.wShowWindow = SW_HIDE;
3357
3358 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003359 s2,
3360 NULL,
3361 NULL,
3362 TRUE,
3363 CREATE_NEW_CONSOLE,
3364 NULL,
3365 NULL,
3366 &siStartInfo,
3367 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003368 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003369 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003370
Mark Hammondb37a3732000-08-14 04:47:33 +00003371 /* Return process handle */
3372 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003373 return TRUE;
3374 }
Tim Peters402d5982001-08-27 06:37:48 +00003375 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003376 return FALSE;
3377}
3378
3379/* The following code is based off of KB: Q190351 */
3380
3381static PyObject *
3382_PyPopen(char *cmdstring, int mode, int n)
3383{
3384 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3385 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003386 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003387
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003388 SECURITY_ATTRIBUTES saAttr;
3389 BOOL fSuccess;
3390 int fd1, fd2, fd3;
3391 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003392 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003393 PyObject *f;
3394
3395 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3396 saAttr.bInheritHandle = TRUE;
3397 saAttr.lpSecurityDescriptor = NULL;
3398
3399 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3400 return win32_error("CreatePipe", NULL);
3401
3402 /* Create new output read handle and the input write handle. Set
3403 * the inheritance properties to FALSE. Otherwise, the child inherits
3404 * the these handles; resulting in non-closeable handles to the pipes
3405 * being created. */
3406 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003407 GetCurrentProcess(), &hChildStdinWrDup, 0,
3408 FALSE,
3409 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003410 if (!fSuccess)
3411 return win32_error("DuplicateHandle", NULL);
3412
3413 /* Close the inheritable version of ChildStdin
3414 that we're using. */
3415 CloseHandle(hChildStdinWr);
3416
3417 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3418 return win32_error("CreatePipe", NULL);
3419
3420 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003421 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3422 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003423 if (!fSuccess)
3424 return win32_error("DuplicateHandle", NULL);
3425
3426 /* Close the inheritable version of ChildStdout
3427 that we're using. */
3428 CloseHandle(hChildStdoutRd);
3429
3430 if (n != POPEN_4) {
3431 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3432 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003433 fSuccess = DuplicateHandle(GetCurrentProcess(),
3434 hChildStderrRd,
3435 GetCurrentProcess(),
3436 &hChildStderrRdDup, 0,
3437 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003438 if (!fSuccess)
3439 return win32_error("DuplicateHandle", NULL);
3440 /* Close the inheritable version of ChildStdErr that we're using. */
3441 CloseHandle(hChildStderrRd);
3442 }
Tim Peters5aa91602002-01-30 05:46:57 +00003443
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003444 switch (n) {
3445 case POPEN_1:
3446 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3447 case _O_WRONLY | _O_TEXT:
3448 /* Case for writing to child Stdin in text mode. */
3449 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3450 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003451 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003452 PyFile_SetBufSize(f, 0);
3453 /* We don't care about these pipes anymore, so close them. */
3454 CloseHandle(hChildStdoutRdDup);
3455 CloseHandle(hChildStderrRdDup);
3456 break;
3457
3458 case _O_RDONLY | _O_TEXT:
3459 /* Case for reading from child Stdout in text mode. */
3460 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3461 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003462 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003463 PyFile_SetBufSize(f, 0);
3464 /* We don't care about these pipes anymore, so close them. */
3465 CloseHandle(hChildStdinWrDup);
3466 CloseHandle(hChildStderrRdDup);
3467 break;
3468
3469 case _O_RDONLY | _O_BINARY:
3470 /* Case for readinig from child Stdout in binary mode. */
3471 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3472 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003473 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003474 PyFile_SetBufSize(f, 0);
3475 /* We don't care about these pipes anymore, so close them. */
3476 CloseHandle(hChildStdinWrDup);
3477 CloseHandle(hChildStderrRdDup);
3478 break;
3479
3480 case _O_WRONLY | _O_BINARY:
3481 /* Case for writing to child Stdin in binary mode. */
3482 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3483 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003484 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003485 PyFile_SetBufSize(f, 0);
3486 /* We don't care about these pipes anymore, so close them. */
3487 CloseHandle(hChildStdoutRdDup);
3488 CloseHandle(hChildStderrRdDup);
3489 break;
3490 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003491 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003492 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003493
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003494 case POPEN_2:
3495 case POPEN_4:
3496 {
3497 char *m1, *m2;
3498 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003499
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003500 if (mode && _O_TEXT) {
3501 m1 = "r";
3502 m2 = "w";
3503 } else {
3504 m1 = "rb";
3505 m2 = "wb";
3506 }
3507
3508 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3509 f1 = _fdopen(fd1, m2);
3510 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3511 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003512 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003513 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003514 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003515 PyFile_SetBufSize(p2, 0);
3516
3517 if (n != 4)
3518 CloseHandle(hChildStderrRdDup);
3519
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003520 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003521 Py_XDECREF(p1);
3522 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003523 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003524 break;
3525 }
Tim Peters5aa91602002-01-30 05:46:57 +00003526
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003527 case POPEN_3:
3528 {
3529 char *m1, *m2;
3530 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003531
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003532 if (mode && _O_TEXT) {
3533 m1 = "r";
3534 m2 = "w";
3535 } else {
3536 m1 = "rb";
3537 m2 = "wb";
3538 }
3539
3540 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3541 f1 = _fdopen(fd1, m2);
3542 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3543 f2 = _fdopen(fd2, m1);
3544 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3545 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003546 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003547 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3548 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003549 PyFile_SetBufSize(p1, 0);
3550 PyFile_SetBufSize(p2, 0);
3551 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003552 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003553 Py_XDECREF(p1);
3554 Py_XDECREF(p2);
3555 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003556 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003557 break;
3558 }
3559 }
3560
3561 if (n == POPEN_4) {
3562 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003563 hChildStdinRd,
3564 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003565 hChildStdoutWr,
3566 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003567 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003568 }
3569 else {
3570 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003571 hChildStdinRd,
3572 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003573 hChildStderrWr,
3574 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003575 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003576 }
3577
Mark Hammondb37a3732000-08-14 04:47:33 +00003578 /*
3579 * Insert the files we've created into the process dictionary
3580 * all referencing the list with the process handle and the
3581 * initial number of files (see description below in _PyPclose).
3582 * Since if _PyPclose later tried to wait on a process when all
3583 * handles weren't closed, it could create a deadlock with the
3584 * child, we spend some energy here to try to ensure that we
3585 * either insert all file handles into the dictionary or none
3586 * at all. It's a little clumsy with the various popen modes
3587 * and variable number of files involved.
3588 */
3589 if (!_PyPopenProcs) {
3590 _PyPopenProcs = PyDict_New();
3591 }
3592
3593 if (_PyPopenProcs) {
3594 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3595 int ins_rc[3];
3596
3597 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3598 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3599
3600 procObj = PyList_New(2);
3601 hProcessObj = PyLong_FromVoidPtr(hProcess);
3602 intObj = PyInt_FromLong(file_count);
3603
3604 if (procObj && hProcessObj && intObj) {
3605 PyList_SetItem(procObj,0,hProcessObj);
3606 PyList_SetItem(procObj,1,intObj);
3607
3608 fileObj[0] = PyLong_FromVoidPtr(f1);
3609 if (fileObj[0]) {
3610 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3611 fileObj[0],
3612 procObj);
3613 }
3614 if (file_count >= 2) {
3615 fileObj[1] = PyLong_FromVoidPtr(f2);
3616 if (fileObj[1]) {
3617 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3618 fileObj[1],
3619 procObj);
3620 }
3621 }
3622 if (file_count >= 3) {
3623 fileObj[2] = PyLong_FromVoidPtr(f3);
3624 if (fileObj[2]) {
3625 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3626 fileObj[2],
3627 procObj);
3628 }
3629 }
3630
3631 if (ins_rc[0] < 0 || !fileObj[0] ||
3632 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3633 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3634 /* Something failed - remove any dictionary
3635 * entries that did make it.
3636 */
3637 if (!ins_rc[0] && fileObj[0]) {
3638 PyDict_DelItem(_PyPopenProcs,
3639 fileObj[0]);
3640 }
3641 if (!ins_rc[1] && fileObj[1]) {
3642 PyDict_DelItem(_PyPopenProcs,
3643 fileObj[1]);
3644 }
3645 if (!ins_rc[2] && fileObj[2]) {
3646 PyDict_DelItem(_PyPopenProcs,
3647 fileObj[2]);
3648 }
3649 }
3650 }
Tim Peters5aa91602002-01-30 05:46:57 +00003651
Mark Hammondb37a3732000-08-14 04:47:33 +00003652 /*
3653 * Clean up our localized references for the dictionary keys
3654 * and value since PyDict_SetItem will Py_INCREF any copies
3655 * that got placed in the dictionary.
3656 */
3657 Py_XDECREF(procObj);
3658 Py_XDECREF(fileObj[0]);
3659 Py_XDECREF(fileObj[1]);
3660 Py_XDECREF(fileObj[2]);
3661 }
3662
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003663 /* Child is launched. Close the parents copy of those pipe
3664 * handles that only the child should have open. You need to
3665 * make sure that no handles to the write end of the output pipe
3666 * are maintained in this process or else the pipe will not close
3667 * when the child process exits and the ReadFile will hang. */
3668
3669 if (!CloseHandle(hChildStdinRd))
3670 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003671
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003672 if (!CloseHandle(hChildStdoutWr))
3673 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003674
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003675 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3676 return win32_error("CloseHandle", NULL);
3677
3678 return f;
3679}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003680
3681/*
3682 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3683 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003684 *
3685 * This function uses the _PyPopenProcs dictionary in order to map the
3686 * input file pointer to information about the process that was
3687 * originally created by the popen* call that created the file pointer.
3688 * The dictionary uses the file pointer as a key (with one entry
3689 * inserted for each file returned by the original popen* call) and a
3690 * single list object as the value for all files from a single call.
3691 * The list object contains the Win32 process handle at [0], and a file
3692 * count at [1], which is initialized to the total number of file
3693 * handles using that list.
3694 *
3695 * This function closes whichever handle it is passed, and decrements
3696 * the file count in the dictionary for the process handle pointed to
3697 * by this file. On the last close (when the file count reaches zero),
3698 * this function will wait for the child process and then return its
3699 * exit code as the result of the close() operation. This permits the
3700 * files to be closed in any order - it is always the close() of the
3701 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003702 */
Tim Peters736aa322000-09-01 06:51:24 +00003703
3704 /* RED_FLAG 31-Aug-2000 Tim
3705 * This is always called (today!) between a pair of
3706 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3707 * macros. So the thread running this has no valid thread state, as
3708 * far as Python is concerned. However, this calls some Python API
3709 * functions that cannot be called safely without a valid thread
3710 * state, in particular PyDict_GetItem.
3711 * As a temporary hack (although it may last for years ...), we
3712 * *rely* on not having a valid thread state in this function, in
3713 * order to create our own "from scratch".
3714 * This will deadlock if _PyPclose is ever called by a thread
3715 * holding the global lock.
3716 */
3717
Fredrik Lundh56055a42000-07-23 19:47:12 +00003718static int _PyPclose(FILE *file)
3719{
Fredrik Lundh20318932000-07-26 17:29:12 +00003720 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003721 DWORD exit_code;
3722 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003723 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3724 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003725#ifdef WITH_THREAD
3726 PyInterpreterState* pInterpreterState;
3727 PyThreadState* pThreadState;
3728#endif
3729
Fredrik Lundh20318932000-07-26 17:29:12 +00003730 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003731 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003732 */
3733 result = fclose(file);
3734
Tim Peters736aa322000-09-01 06:51:24 +00003735#ifdef WITH_THREAD
3736 /* Bootstrap a valid thread state into existence. */
3737 pInterpreterState = PyInterpreterState_New();
3738 if (!pInterpreterState) {
3739 /* Well, we're hosed now! We don't have a thread
3740 * state, so can't call a nice error routine, or raise
3741 * an exception. Just die.
3742 */
3743 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003744 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003745 return -1; /* unreachable */
3746 }
3747 pThreadState = PyThreadState_New(pInterpreterState);
3748 if (!pThreadState) {
3749 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003750 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003751 return -1; /* unreachable */
3752 }
3753 /* Grab the global lock. Note that this will deadlock if the
3754 * current thread already has the lock! (see RED_FLAG comments
3755 * before this function)
3756 */
3757 PyEval_RestoreThread(pThreadState);
3758#endif
3759
Fredrik Lundh56055a42000-07-23 19:47:12 +00003760 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003761 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3762 (procObj = PyDict_GetItem(_PyPopenProcs,
3763 fileObj)) != NULL &&
3764 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3765 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3766
3767 hProcess = PyLong_AsVoidPtr(hProcessObj);
3768 file_count = PyInt_AsLong(intObj);
3769
3770 if (file_count > 1) {
3771 /* Still other files referencing process */
3772 file_count--;
3773 PyList_SetItem(procObj,1,
3774 PyInt_FromLong(file_count));
3775 } else {
3776 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003777 if (result != EOF &&
3778 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3779 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003780 /* Possible truncation here in 16-bit environments, but
3781 * real exit codes are just the lower byte in any event.
3782 */
3783 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003784 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003785 /* Indicate failure - this will cause the file object
3786 * to raise an I/O error and translate the last Win32
3787 * error code from errno. We do have a problem with
3788 * last errors that overlap the normal errno table,
3789 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003790 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003791 if (result != EOF) {
3792 /* If the error wasn't from the fclose(), then
3793 * set errno for the file object error handling.
3794 */
3795 errno = GetLastError();
3796 }
3797 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003798 }
3799
3800 /* Free up the native handle at this point */
3801 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003802 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003803
Mark Hammondb37a3732000-08-14 04:47:33 +00003804 /* Remove this file pointer from dictionary */
3805 PyDict_DelItem(_PyPopenProcs, fileObj);
3806
3807 if (PyDict_Size(_PyPopenProcs) == 0) {
3808 Py_DECREF(_PyPopenProcs);
3809 _PyPopenProcs = NULL;
3810 }
3811
3812 } /* if object retrieval ok */
3813
3814 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003815 } /* if _PyPopenProcs */
3816
Tim Peters736aa322000-09-01 06:51:24 +00003817#ifdef WITH_THREAD
3818 /* Tear down the thread & interpreter states.
3819 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003820 * call the thread clear & delete functions, and indeed insist on
3821 * doing that themselves. The lock must be held during the clear, but
3822 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003823 */
3824 PyInterpreterState_Clear(pInterpreterState);
3825 PyEval_ReleaseThread(pThreadState);
3826 PyInterpreterState_Delete(pInterpreterState);
3827#endif
3828
Fredrik Lundh56055a42000-07-23 19:47:12 +00003829 return result;
3830}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003831
3832#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003834posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003835{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003836 char *name;
3837 char *mode = "r";
3838 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003839 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003840 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003841 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003842 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003843 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003844 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003845 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003846 if (fp == NULL)
3847 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003848 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003849 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003850 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003851 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003852}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003853
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003854#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003855#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003856
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003857
Guido van Rossumb6775db1994-08-01 11:34:53 +00003858#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003859PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003860"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003861Set the current process's user id.");
3862
Barry Warsaw53699e91996-12-10 23:23:01 +00003863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003864posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003865{
3866 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003867 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003868 return NULL;
3869 if (setuid(uid) < 0)
3870 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003871 Py_INCREF(Py_None);
3872 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003873}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003874#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003875
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003876
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003877#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003878PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003879"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003880Set the current process's effective user id.");
3881
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003882static PyObject *
3883posix_seteuid (PyObject *self, PyObject *args)
3884{
3885 int euid;
3886 if (!PyArg_ParseTuple(args, "i", &euid)) {
3887 return NULL;
3888 } else if (seteuid(euid) < 0) {
3889 return posix_error();
3890 } else {
3891 Py_INCREF(Py_None);
3892 return Py_None;
3893 }
3894}
3895#endif /* HAVE_SETEUID */
3896
3897#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003899"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003900Set the current process's effective group id.");
3901
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003902static PyObject *
3903posix_setegid (PyObject *self, PyObject *args)
3904{
3905 int egid;
3906 if (!PyArg_ParseTuple(args, "i", &egid)) {
3907 return NULL;
3908 } else if (setegid(egid) < 0) {
3909 return posix_error();
3910 } else {
3911 Py_INCREF(Py_None);
3912 return Py_None;
3913 }
3914}
3915#endif /* HAVE_SETEGID */
3916
3917#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003918PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003919"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003920Set the current process's real and effective user ids.");
3921
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003922static PyObject *
3923posix_setreuid (PyObject *self, PyObject *args)
3924{
3925 int ruid, euid;
3926 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3927 return NULL;
3928 } else if (setreuid(ruid, euid) < 0) {
3929 return posix_error();
3930 } else {
3931 Py_INCREF(Py_None);
3932 return Py_None;
3933 }
3934}
3935#endif /* HAVE_SETREUID */
3936
3937#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003938PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003939"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003940Set the current process's real and effective group ids.");
3941
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003942static PyObject *
3943posix_setregid (PyObject *self, PyObject *args)
3944{
3945 int rgid, egid;
3946 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3947 return NULL;
3948 } else if (setregid(rgid, egid) < 0) {
3949 return posix_error();
3950 } else {
3951 Py_INCREF(Py_None);
3952 return Py_None;
3953 }
3954}
3955#endif /* HAVE_SETREGID */
3956
Guido van Rossumb6775db1994-08-01 11:34:53 +00003957#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003958PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003959"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003960Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003961
Barry Warsaw53699e91996-12-10 23:23:01 +00003962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003963posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003964{
3965 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003966 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003967 return NULL;
3968 if (setgid(gid) < 0)
3969 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003970 Py_INCREF(Py_None);
3971 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003972}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003973#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003974
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003975#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003976PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003977"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003978Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003979
3980static PyObject *
3981posix_setgroups(PyObject *self, PyObject *args)
3982{
3983 PyObject *groups;
3984 int i, len;
3985 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00003986
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00003987 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
3988 return NULL;
3989 if (!PySequence_Check(groups)) {
3990 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
3991 return NULL;
3992 }
3993 len = PySequence_Size(groups);
3994 if (len > MAX_GROUPS) {
3995 PyErr_SetString(PyExc_ValueError, "too many groups");
3996 return NULL;
3997 }
3998 for(i = 0; i < len; i++) {
3999 PyObject *elem;
4000 elem = PySequence_GetItem(groups, i);
4001 if (!elem)
4002 return NULL;
4003 if (!PyInt_Check(elem)) {
4004 PyErr_SetString(PyExc_TypeError,
4005 "groups must be integers");
4006 Py_DECREF(elem);
4007 return NULL;
4008 }
4009 /* XXX: check that value fits into gid_t. */
4010 grouplist[i] = PyInt_AsLong(elem);
4011 Py_DECREF(elem);
4012 }
4013
4014 if (setgroups(len, grouplist) < 0)
4015 return posix_error();
4016 Py_INCREF(Py_None);
4017 return Py_None;
4018}
4019#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004020
Guido van Rossumb6775db1994-08-01 11:34:53 +00004021#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004022PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004023"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004024Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004025
Barry Warsaw53699e91996-12-10 23:23:01 +00004026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004027posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004028{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004029 int pid, options;
4030#ifdef UNION_WAIT
4031 union wait status;
4032#define status_i (status.w_status)
4033#else
4034 int status;
4035#define status_i status
4036#endif
4037 status_i = 0;
4038
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004039 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004040 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004041 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004042 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004043 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004044 if (pid == -1)
4045 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004046 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004047 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004048}
4049
Tim Petersab034fa2002-02-01 11:27:43 +00004050#elif defined(HAVE_CWAIT)
4051
4052/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004053PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004054"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004055"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004056
4057static PyObject *
4058posix_waitpid(PyObject *self, PyObject *args)
4059{
4060 int pid, options;
4061 int status;
4062
4063 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4064 return NULL;
4065 Py_BEGIN_ALLOW_THREADS
4066 pid = _cwait(&status, pid, options);
4067 Py_END_ALLOW_THREADS
4068 if (pid == -1)
4069 return posix_error();
4070 else
4071 /* shift the status left a byte so this is more like the
4072 POSIX waitpid */
4073 return Py_BuildValue("ii", pid, status << 8);
4074}
4075#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004076
Guido van Rossumad0ee831995-03-01 10:34:45 +00004077#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004078PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004079"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004080Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004081
Barry Warsaw53699e91996-12-10 23:23:01 +00004082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004083posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004084{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004085 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004086#ifdef UNION_WAIT
4087 union wait status;
4088#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004089#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004090 int status;
4091#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004092#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004093 if (!PyArg_ParseTuple(args, ":wait"))
4094 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004095 status_i = 0;
4096 Py_BEGIN_ALLOW_THREADS
4097 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004098 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004099 if (pid == -1)
4100 return posix_error();
4101 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004102 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004103#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004104}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004105#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004108PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004109"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004110Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004111
Barry Warsaw53699e91996-12-10 23:23:01 +00004112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004113posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004114{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004115#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004116 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004117#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004118 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004119#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004120}
4121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004122
Guido van Rossumb6775db1994-08-01 11:34:53 +00004123#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004124PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004125"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004126Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004127
Barry Warsaw53699e91996-12-10 23:23:01 +00004128static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004129posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004130{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004131 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004132 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004133 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004134 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004135 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004136 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004137 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004138 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004139 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004140 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004141 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004142}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004143#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004145
Guido van Rossumb6775db1994-08-01 11:34:53 +00004146#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004147PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004148"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004149Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004150
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004152posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004153{
Mark Hammondef8b6542001-05-13 08:04:26 +00004154 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004155}
4156#endif /* HAVE_SYMLINK */
4157
4158
4159#ifdef HAVE_TIMES
4160#ifndef HZ
4161#define HZ 60 /* Universal constant :-) */
4162#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004163
Guido van Rossumd48f2521997-12-05 22:19:34 +00004164#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4165static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004166system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004167{
4168 ULONG value = 0;
4169
4170 Py_BEGIN_ALLOW_THREADS
4171 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4172 Py_END_ALLOW_THREADS
4173
4174 return value;
4175}
4176
4177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004178posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004179{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004180 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004181 return NULL;
4182
4183 /* Currently Only Uptime is Provided -- Others Later */
4184 return Py_BuildValue("ddddd",
4185 (double)0 /* t.tms_utime / HZ */,
4186 (double)0 /* t.tms_stime / HZ */,
4187 (double)0 /* t.tms_cutime / HZ */,
4188 (double)0 /* t.tms_cstime / HZ */,
4189 (double)system_uptime() / 1000);
4190}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004191#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004193posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004194{
4195 struct tms t;
4196 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004197 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004198 return NULL;
4199 errno = 0;
4200 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004201 if (c == (clock_t) -1)
4202 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004203 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004204 (double)t.tms_utime / HZ,
4205 (double)t.tms_stime / HZ,
4206 (double)t.tms_cutime / HZ,
4207 (double)t.tms_cstime / HZ,
4208 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004209}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004210#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004211#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004212
4213
Guido van Rossum87755a21996-09-07 00:59:43 +00004214#ifdef MS_WIN32
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004215#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004216static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004217posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004218{
4219 FILETIME create, exit, kernel, user;
4220 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004221 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004222 return NULL;
4223 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004224 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4225 /* The fields of a FILETIME structure are the hi and lo part
4226 of a 64-bit value expressed in 100 nanosecond units.
4227 1e7 is one second in such units; 1e-7 the inverse.
4228 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4229 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004230 return Py_BuildValue(
4231 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004232 (double)(kernel.dwHighDateTime*429.4967296 +
4233 kernel.dwLowDateTime*1e-7),
4234 (double)(user.dwHighDateTime*429.4967296 +
4235 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004236 (double)0,
4237 (double)0,
4238 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004239}
Guido van Rossum8d665e61996-06-26 18:22:49 +00004240#endif /* MS_WIN32 */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004241
4242#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004243PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004244"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004245Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004246#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004247
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004248
Guido van Rossumb6775db1994-08-01 11:34:53 +00004249#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004250PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004251"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004252Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004253
Barry Warsaw53699e91996-12-10 23:23:01 +00004254static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004255posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004256{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004257 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004258 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004259 if (setsid() < 0)
4260 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004261 Py_INCREF(Py_None);
4262 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004263}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004264#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004265
Guido van Rossumb6775db1994-08-01 11:34:53 +00004266#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004267PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004268"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004269Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004270
Barry Warsaw53699e91996-12-10 23:23:01 +00004271static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004272posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004273{
4274 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004275 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004276 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004277 if (setpgid(pid, pgrp) < 0)
4278 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004279 Py_INCREF(Py_None);
4280 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004281}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004282#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004283
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004284
Guido van Rossumb6775db1994-08-01 11:34:53 +00004285#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004286PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004287"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004288Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004289
Barry Warsaw53699e91996-12-10 23:23:01 +00004290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004291posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004292{
4293 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004294 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004295 return NULL;
4296 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004297 if (pgid < 0)
4298 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004299 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004300}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004301#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004302
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004303
Guido van Rossumb6775db1994-08-01 11:34:53 +00004304#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004305PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004306"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004307Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004308
Barry Warsaw53699e91996-12-10 23:23:01 +00004309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004310posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004311{
4312 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004313 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004314 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004315 if (tcsetpgrp(fd, pgid) < 0)
4316 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004317 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004318 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004319}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004320#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004321
Guido van Rossum687dd131993-05-17 08:34:16 +00004322/* Functions acting on file descriptors */
4323
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004324PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004325"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004326Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004327
Barry Warsaw53699e91996-12-10 23:23:01 +00004328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004329posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004330{
Mark Hammondef8b6542001-05-13 08:04:26 +00004331 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004332 int flag;
4333 int mode = 0777;
4334 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004335 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004336 Py_FileSystemDefaultEncoding, &file,
4337 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004338 return NULL;
4339
Barry Warsaw53699e91996-12-10 23:23:01 +00004340 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004341 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004342 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004343 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004344 return posix_error_with_allocated_filename(file);
4345 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004346 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004347}
4348
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004349
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004350PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004351"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004352Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004353
Barry Warsaw53699e91996-12-10 23:23:01 +00004354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004355posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004356{
4357 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004358 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004359 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004360 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004361 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004362 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004363 if (res < 0)
4364 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004365 Py_INCREF(Py_None);
4366 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004367}
4368
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004369
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004370PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004371"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004372Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004373
Barry Warsaw53699e91996-12-10 23:23:01 +00004374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004375posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004376{
4377 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004378 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004379 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004380 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004381 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004382 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004383 if (fd < 0)
4384 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004385 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004386}
4387
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004388
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004389PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004390"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004391Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004392
Barry Warsaw53699e91996-12-10 23:23:01 +00004393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004394posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004395{
4396 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004397 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004398 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004399 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004400 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004401 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004402 if (res < 0)
4403 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004404 Py_INCREF(Py_None);
4405 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004406}
4407
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004408
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004409PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004410"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004411Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004412
Barry Warsaw53699e91996-12-10 23:23:01 +00004413static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004414posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004415{
4416 int fd, how;
Tim Peters6e13a562001-09-06 00:32:15 +00004417#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004418 LONG_LONG pos, res;
4419#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004420 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004421#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004422 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004423 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004424 return NULL;
4425#ifdef SEEK_SET
4426 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4427 switch (how) {
4428 case 0: how = SEEK_SET; break;
4429 case 1: how = SEEK_CUR; break;
4430 case 2: how = SEEK_END; break;
4431 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004432#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004433
4434#if !defined(HAVE_LARGEFILE_SUPPORT)
4435 pos = PyInt_AsLong(posobj);
4436#else
4437 pos = PyLong_Check(posobj) ?
4438 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4439#endif
4440 if (PyErr_Occurred())
4441 return NULL;
4442
Barry Warsaw53699e91996-12-10 23:23:01 +00004443 Py_BEGIN_ALLOW_THREADS
Tim Peters6e13a562001-09-06 00:32:15 +00004444#if defined(MS_WIN64) || defined(MS_WIN32)
Fred Drake699f3522000-06-29 21:12:41 +00004445 res = _lseeki64(fd, pos, how);
4446#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004447 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004448#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004449 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004450 if (res < 0)
4451 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004452
4453#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004454 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004455#else
4456 return PyLong_FromLongLong(res);
4457#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004458}
4459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004460
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004461PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004462"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004463Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004464
Barry Warsaw53699e91996-12-10 23:23:01 +00004465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004466posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004467{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004468 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004469 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004470 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004471 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004472 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004473 if (buffer == NULL)
4474 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004475 Py_BEGIN_ALLOW_THREADS
4476 n = read(fd, PyString_AsString(buffer), size);
4477 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004478 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004479 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004480 return posix_error();
4481 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004482 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004483 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004484 return buffer;
4485}
4486
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004487
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004488PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004489"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004490Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004491
Barry Warsaw53699e91996-12-10 23:23:01 +00004492static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004493posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004494{
4495 int fd, size;
4496 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004497 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004498 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004499 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004500 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004501 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004502 if (size < 0)
4503 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004504 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004505}
4506
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004507
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004508PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004509"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004510Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004511
Barry Warsaw53699e91996-12-10 23:23:01 +00004512static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004513posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004514{
4515 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004516 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004517 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004518 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004519 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004520 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004521 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004522 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004523 if (res != 0)
4524 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004525
Fred Drake699f3522000-06-29 21:12:41 +00004526 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004527}
4528
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004530PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004531"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004532Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004533
Barry Warsaw53699e91996-12-10 23:23:01 +00004534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004535posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004536{
Guido van Rossum687dd131993-05-17 08:34:16 +00004537 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004538 char *mode = "r";
4539 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004540 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004541 PyObject *f;
4542 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004543 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004544
Barry Warsaw53699e91996-12-10 23:23:01 +00004545 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004546 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004547 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004548 if (fp == NULL)
4549 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004550 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004551 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004552 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004553 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004554}
4555
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004556PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004557"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004558Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004559connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004560
4561static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004562posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004563{
4564 int fd;
4565 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4566 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004567 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004568}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004569
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004570#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004571PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004572"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004573Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004574
Barry Warsaw53699e91996-12-10 23:23:01 +00004575static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004576posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004577{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004578#if defined(PYOS_OS2)
4579 HFILE read, write;
4580 APIRET rc;
4581
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004582 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004583 return NULL;
4584
4585 Py_BEGIN_ALLOW_THREADS
4586 rc = DosCreatePipe( &read, &write, 4096);
4587 Py_END_ALLOW_THREADS
4588 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004589 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004590
4591 return Py_BuildValue("(ii)", read, write);
4592#else
Guido van Rossum8d665e61996-06-26 18:22:49 +00004593#if !defined(MS_WIN32)
Guido van Rossum687dd131993-05-17 08:34:16 +00004594 int fds[2];
4595 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004596 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004597 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004598 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004599 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004600 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004601 if (res != 0)
4602 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004603 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004604#else /* MS_WIN32 */
Guido van Rossum794d8131994-08-23 13:48:48 +00004605 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004606 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004607 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004608 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004609 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004610 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004611 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004612 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004613 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004614 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004615 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4616 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004617 return Py_BuildValue("(ii)", read_fd, write_fd);
Guido van Rossum8d665e61996-06-26 18:22:49 +00004618#endif /* MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004619#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004620}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004621#endif /* HAVE_PIPE */
4622
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004623
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004624#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004625PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004626"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004627Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004628
Barry Warsaw53699e91996-12-10 23:23:01 +00004629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004630posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004631{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004632 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004633 int mode = 0666;
4634 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004635 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004636 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004637 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004638 res = mkfifo(filename, mode);
4639 Py_END_ALLOW_THREADS
4640 if (res < 0)
4641 return posix_error();
4642 Py_INCREF(Py_None);
4643 return Py_None;
4644}
4645#endif
4646
4647
4648#ifdef HAVE_MKNOD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004649PyDoc_STRVAR(posix_mknod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004650"mknod(filename, [, mode=0600, major, minor])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004651Create a filesystem node (file, device special file or named pipe)\n\
4652named filename. mode specifies both the permissions to use and the\n\
4653type of node to be created, being combined (bitwise OR) with one of\n\
4654S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4655major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004656they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004657
4658
4659static PyObject *
4660posix_mknod(PyObject *self, PyObject *args)
4661{
4662 char *filename;
4663 int mode = 0600;
4664 int major = 0;
4665 int minor = 0;
4666 int res;
4667 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4668 &mode, &major, &minor))
4669 return NULL;
4670 Py_BEGIN_ALLOW_THREADS
4671 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004672 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004673 if (res < 0)
4674 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004675 Py_INCREF(Py_None);
4676 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004677}
4678#endif
4679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004680
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004681#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004682PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004683"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004684Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004685
Barry Warsaw53699e91996-12-10 23:23:01 +00004686static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004687posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004688{
4689 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004690 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004691 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004692 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004693
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004694 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004695 return NULL;
4696
4697#if !defined(HAVE_LARGEFILE_SUPPORT)
4698 length = PyInt_AsLong(lenobj);
4699#else
4700 length = PyLong_Check(lenobj) ?
4701 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4702#endif
4703 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004704 return NULL;
4705
Barry Warsaw53699e91996-12-10 23:23:01 +00004706 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004707 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004708 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004709 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004710 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004711 return NULL;
4712 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004713 Py_INCREF(Py_None);
4714 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004715}
4716#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004717
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004718#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004719PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004720"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004721Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004722
Fred Drake762e2061999-08-26 17:23:54 +00004723/* Save putenv() parameters as values here, so we can collect them when they
4724 * get re-set with another call for the same key. */
4725static PyObject *posix_putenv_garbage;
4726
Tim Peters5aa91602002-01-30 05:46:57 +00004727static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004728posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004729{
4730 char *s1, *s2;
4731 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004732 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004733 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004734
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004735 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004736 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004737
4738#if defined(PYOS_OS2)
4739 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4740 APIRET rc;
4741
4742 if (strlen(s2) == 0) /* If New Value is an Empty String */
4743 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4744
4745 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4746 if (rc != NO_ERROR)
4747 return os2_error(rc);
4748
4749 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4750 APIRET rc;
4751
4752 if (strlen(s2) == 0) /* If New Value is an Empty String */
4753 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4754
4755 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4756 if (rc != NO_ERROR)
4757 return os2_error(rc);
4758 } else {
4759#endif
4760
Fred Drake762e2061999-08-26 17:23:54 +00004761 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004762 len = strlen(s1) + strlen(s2) + 2;
4763 /* len includes space for a trailing \0; the size arg to
4764 PyString_FromStringAndSize does not count that */
4765 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004766 if (newstr == NULL)
4767 return PyErr_NoMemory();
4768 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004769 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004770 if (putenv(new)) {
4771 posix_error();
4772 return NULL;
4773 }
Fred Drake762e2061999-08-26 17:23:54 +00004774 /* Install the first arg and newstr in posix_putenv_garbage;
4775 * this will cause previous value to be collected. This has to
4776 * happen after the real putenv() call because the old value
4777 * was still accessible until then. */
4778 if (PyDict_SetItem(posix_putenv_garbage,
4779 PyTuple_GET_ITEM(args, 0), newstr)) {
4780 /* really not much we can do; just leak */
4781 PyErr_Clear();
4782 }
4783 else {
4784 Py_DECREF(newstr);
4785 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004786
4787#if defined(PYOS_OS2)
4788 }
4789#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004790 Py_INCREF(Py_None);
4791 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004792}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004793#endif /* putenv */
4794
Guido van Rossumc524d952001-10-19 01:31:59 +00004795#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004796PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004797"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004798Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00004799
4800static PyObject *
4801posix_unsetenv(PyObject *self, PyObject *args)
4802{
4803 char *s1;
4804
4805 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4806 return NULL;
4807
4808 unsetenv(s1);
4809
4810 /* Remove the key from posix_putenv_garbage;
4811 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004812 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004813 * old value was still accessible until then.
4814 */
4815 if (PyDict_DelItem(posix_putenv_garbage,
4816 PyTuple_GET_ITEM(args, 0))) {
4817 /* really not much we can do; just leak */
4818 PyErr_Clear();
4819 }
4820
4821 Py_INCREF(Py_None);
4822 return Py_None;
4823}
4824#endif /* unsetenv */
4825
Guido van Rossumb6a47161997-09-15 22:54:34 +00004826#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004827PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004828"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004829Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004830
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004831static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004832posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004833{
4834 int code;
4835 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004836 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004837 return NULL;
4838 message = strerror(code);
4839 if (message == NULL) {
4840 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004841 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004842 return NULL;
4843 }
4844 return PyString_FromString(message);
4845}
4846#endif /* strerror */
4847
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004848
Guido van Rossumc9641791998-08-04 15:26:23 +00004849#ifdef HAVE_SYS_WAIT_H
4850
Fred Drake106c1a02002-04-23 15:58:02 +00004851#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004852PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004853"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004854Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00004855
4856static PyObject *
4857posix_WCOREDUMP(PyObject *self, PyObject *args)
4858{
4859#ifdef UNION_WAIT
4860 union wait status;
4861#define status_i (status.w_status)
4862#else
4863 int status;
4864#define status_i status
4865#endif
4866 status_i = 0;
4867
4868 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4869 {
4870 return NULL;
4871 }
4872
4873 return PyBool_FromLong(WCOREDUMP(status));
4874#undef status_i
4875}
4876#endif /* WCOREDUMP */
4877
4878#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004879PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004880"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004881Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004882job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00004883
4884static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004885posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004886{
4887#ifdef UNION_WAIT
4888 union wait status;
4889#define status_i (status.w_status)
4890#else
4891 int status;
4892#define status_i status
4893#endif
4894 status_i = 0;
4895
4896 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4897 {
4898 return NULL;
4899 }
4900
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004901 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004902#undef status_i
4903}
4904#endif /* WIFCONTINUED */
4905
Guido van Rossumc9641791998-08-04 15:26:23 +00004906#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004907PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004908"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004910
4911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004912posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004913{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004914#ifdef UNION_WAIT
4915 union wait status;
4916#define status_i (status.w_status)
4917#else
4918 int status;
4919#define status_i status
4920#endif
4921 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004922
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004923 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004924 {
4925 return NULL;
4926 }
Tim Peters5aa91602002-01-30 05:46:57 +00004927
Fred Drake106c1a02002-04-23 15:58:02 +00004928 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004929#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004930}
4931#endif /* WIFSTOPPED */
4932
4933#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004935"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004936Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004937
4938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004939posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004940{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004941#ifdef UNION_WAIT
4942 union wait status;
4943#define status_i (status.w_status)
4944#else
4945 int status;
4946#define status_i status
4947#endif
4948 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004949
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004950 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004951 {
4952 return NULL;
4953 }
Tim Peters5aa91602002-01-30 05:46:57 +00004954
Fred Drake106c1a02002-04-23 15:58:02 +00004955 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004956#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004957}
4958#endif /* WIFSIGNALED */
4959
4960#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004961PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004962"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004963Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004964system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004965
4966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004967posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004968{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004969#ifdef UNION_WAIT
4970 union wait status;
4971#define status_i (status.w_status)
4972#else
4973 int status;
4974#define status_i status
4975#endif
4976 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004977
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004978 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004979 {
4980 return NULL;
4981 }
Tim Peters5aa91602002-01-30 05:46:57 +00004982
Fred Drake106c1a02002-04-23 15:58:02 +00004983 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004984#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004985}
4986#endif /* WIFEXITED */
4987
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004988#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004989PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004990"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004991Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004992
4993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004994posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004995{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004996#ifdef UNION_WAIT
4997 union wait status;
4998#define status_i (status.w_status)
4999#else
5000 int status;
5001#define status_i status
5002#endif
5003 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005004
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005005 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005006 {
5007 return NULL;
5008 }
Tim Peters5aa91602002-01-30 05:46:57 +00005009
Guido van Rossumc9641791998-08-04 15:26:23 +00005010 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005011#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005012}
5013#endif /* WEXITSTATUS */
5014
5015#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005016PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005017"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005018Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005019value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005020
5021static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005022posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005023{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005024#ifdef UNION_WAIT
5025 union wait status;
5026#define status_i (status.w_status)
5027#else
5028 int status;
5029#define status_i status
5030#endif
5031 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005032
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005033 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005034 {
5035 return NULL;
5036 }
Tim Peters5aa91602002-01-30 05:46:57 +00005037
Guido van Rossumc9641791998-08-04 15:26:23 +00005038 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005039#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005040}
5041#endif /* WTERMSIG */
5042
5043#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005044PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005045"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005046Return the signal that stopped the process that provided\n\
5047the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005048
5049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005050posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005051{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005052#ifdef UNION_WAIT
5053 union wait status;
5054#define status_i (status.w_status)
5055#else
5056 int status;
5057#define status_i status
5058#endif
5059 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005060
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005061 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005062 {
5063 return NULL;
5064 }
Tim Peters5aa91602002-01-30 05:46:57 +00005065
Guido van Rossumc9641791998-08-04 15:26:23 +00005066 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005067#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005068}
5069#endif /* WSTOPSIG */
5070
5071#endif /* HAVE_SYS_WAIT_H */
5072
5073
Guido van Rossum94f6f721999-01-06 18:42:14 +00005074#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005075#ifdef _SCO_DS
5076/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5077 needed definitions in sys/statvfs.h */
5078#define _SVID3
5079#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005080#include <sys/statvfs.h>
5081
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005082static PyObject*
5083_pystatvfs_fromstructstatvfs(struct statvfs st) {
5084 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5085 if (v == NULL)
5086 return NULL;
5087
5088#if !defined(HAVE_LARGEFILE_SUPPORT)
5089 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5090 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5091 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5092 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5093 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5094 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5095 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5096 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5097 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5098 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5099#else
5100 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5101 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005102 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005103 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005104 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005105 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5106 PyStructSequence_SET_ITEM(v, 4,
5107 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005108 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005109 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005110 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005111 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005112 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005113 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5114 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5115 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5116#endif
5117
5118 return v;
5119}
5120
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005121PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005122"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005123Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005124
5125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005126posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005127{
5128 int fd, res;
5129 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005130
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005131 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005132 return NULL;
5133 Py_BEGIN_ALLOW_THREADS
5134 res = fstatvfs(fd, &st);
5135 Py_END_ALLOW_THREADS
5136 if (res != 0)
5137 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005138
5139 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005140}
5141#endif /* HAVE_FSTATVFS */
5142
5143
5144#if defined(HAVE_STATVFS)
5145#include <sys/statvfs.h>
5146
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005147PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005148"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005149Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005150
5151static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005152posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005153{
5154 char *path;
5155 int res;
5156 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005157 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005158 return NULL;
5159 Py_BEGIN_ALLOW_THREADS
5160 res = statvfs(path, &st);
5161 Py_END_ALLOW_THREADS
5162 if (res != 0)
5163 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005164
5165 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005166}
5167#endif /* HAVE_STATVFS */
5168
5169
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005170#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005171PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005172"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005173Return a unique name for a temporary file.\n\
5174The directory and a short may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005175or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005176
5177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005178posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005179{
5180 PyObject *result = NULL;
5181 char *dir = NULL;
5182 char *pfx = NULL;
5183 char *name;
5184
5185 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5186 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005187
5188 if (PyErr_Warn(PyExc_RuntimeWarning,
5189 "tempnam is a potential security risk to your program") < 0)
5190 return NULL;
5191
Fred Drake78b71c22001-07-17 20:37:36 +00005192#ifdef MS_WIN32
5193 name = _tempnam(dir, pfx);
5194#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005195 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005196#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005197 if (name == NULL)
5198 return PyErr_NoMemory();
5199 result = PyString_FromString(name);
5200 free(name);
5201 return result;
5202}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005203#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005204
5205
5206#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005207PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005208"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005209Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005210
5211static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005212posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005213{
5214 FILE *fp;
5215
5216 if (!PyArg_ParseTuple(args, ":tmpfile"))
5217 return NULL;
5218 fp = tmpfile();
5219 if (fp == NULL)
5220 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005221 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005222}
5223#endif
5224
5225
5226#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005227PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005228"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005229Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005230
5231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005232posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005233{
5234 char buffer[L_tmpnam];
5235 char *name;
5236
5237 if (!PyArg_ParseTuple(args, ":tmpnam"))
5238 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005239
5240 if (PyErr_Warn(PyExc_RuntimeWarning,
5241 "tmpnam is a potential security risk to your program") < 0)
5242 return NULL;
5243
Greg Wardb48bc172000-03-01 21:51:56 +00005244#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005245 name = tmpnam_r(buffer);
5246#else
5247 name = tmpnam(buffer);
5248#endif
5249 if (name == NULL) {
5250 PyErr_SetObject(PyExc_OSError,
5251 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005252#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005253 "unexpected NULL from tmpnam_r"
5254#else
5255 "unexpected NULL from tmpnam"
5256#endif
5257 ));
5258 return NULL;
5259 }
5260 return PyString_FromString(buffer);
5261}
5262#endif
5263
5264
Fred Drakec9680921999-12-13 16:37:25 +00005265/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5266 * It maps strings representing configuration variable names to
5267 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005268 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005269 * rarely-used constants. There are three separate tables that use
5270 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005271 *
5272 * This code is always included, even if none of the interfaces that
5273 * need it are included. The #if hackery needed to avoid it would be
5274 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005275 */
5276struct constdef {
5277 char *name;
5278 long value;
5279};
5280
Fred Drake12c6e2d1999-12-14 21:25:03 +00005281static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005282conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5283 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005284{
5285 if (PyInt_Check(arg)) {
5286 *valuep = PyInt_AS_LONG(arg);
5287 return 1;
5288 }
5289 if (PyString_Check(arg)) {
5290 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005291 size_t lo = 0;
5292 size_t mid;
5293 size_t hi = tablesize;
5294 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005295 char *confname = PyString_AS_STRING(arg);
5296 while (lo < hi) {
5297 mid = (lo + hi) / 2;
5298 cmp = strcmp(confname, table[mid].name);
5299 if (cmp < 0)
5300 hi = mid;
5301 else if (cmp > 0)
5302 lo = mid + 1;
5303 else {
5304 *valuep = table[mid].value;
5305 return 1;
5306 }
5307 }
5308 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5309 }
5310 else
5311 PyErr_SetString(PyExc_TypeError,
5312 "configuration names must be strings or integers");
5313 return 0;
5314}
5315
5316
5317#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5318static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005319#ifdef _PC_ABI_AIO_XFER_MAX
5320 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5321#endif
5322#ifdef _PC_ABI_ASYNC_IO
5323 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5324#endif
Fred Drakec9680921999-12-13 16:37:25 +00005325#ifdef _PC_ASYNC_IO
5326 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5327#endif
5328#ifdef _PC_CHOWN_RESTRICTED
5329 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5330#endif
5331#ifdef _PC_FILESIZEBITS
5332 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5333#endif
5334#ifdef _PC_LAST
5335 {"PC_LAST", _PC_LAST},
5336#endif
5337#ifdef _PC_LINK_MAX
5338 {"PC_LINK_MAX", _PC_LINK_MAX},
5339#endif
5340#ifdef _PC_MAX_CANON
5341 {"PC_MAX_CANON", _PC_MAX_CANON},
5342#endif
5343#ifdef _PC_MAX_INPUT
5344 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5345#endif
5346#ifdef _PC_NAME_MAX
5347 {"PC_NAME_MAX", _PC_NAME_MAX},
5348#endif
5349#ifdef _PC_NO_TRUNC
5350 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5351#endif
5352#ifdef _PC_PATH_MAX
5353 {"PC_PATH_MAX", _PC_PATH_MAX},
5354#endif
5355#ifdef _PC_PIPE_BUF
5356 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5357#endif
5358#ifdef _PC_PRIO_IO
5359 {"PC_PRIO_IO", _PC_PRIO_IO},
5360#endif
5361#ifdef _PC_SOCK_MAXBUF
5362 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5363#endif
5364#ifdef _PC_SYNC_IO
5365 {"PC_SYNC_IO", _PC_SYNC_IO},
5366#endif
5367#ifdef _PC_VDISABLE
5368 {"PC_VDISABLE", _PC_VDISABLE},
5369#endif
5370};
5371
Fred Drakec9680921999-12-13 16:37:25 +00005372static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005373conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005374{
5375 return conv_confname(arg, valuep, posix_constants_pathconf,
5376 sizeof(posix_constants_pathconf)
5377 / sizeof(struct constdef));
5378}
5379#endif
5380
5381#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005382PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005383"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005384Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005385If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005386
5387static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005388posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005389{
5390 PyObject *result = NULL;
5391 int name, fd;
5392
Fred Drake12c6e2d1999-12-14 21:25:03 +00005393 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5394 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005395 long limit;
5396
5397 errno = 0;
5398 limit = fpathconf(fd, name);
5399 if (limit == -1 && errno != 0)
5400 posix_error();
5401 else
5402 result = PyInt_FromLong(limit);
5403 }
5404 return result;
5405}
5406#endif
5407
5408
5409#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005410PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005411"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005412Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005413If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005414
5415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005416posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005417{
5418 PyObject *result = NULL;
5419 int name;
5420 char *path;
5421
5422 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5423 conv_path_confname, &name)) {
5424 long limit;
5425
5426 errno = 0;
5427 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005428 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005429 if (errno == EINVAL)
5430 /* could be a path or name problem */
5431 posix_error();
5432 else
5433 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005434 }
Fred Drakec9680921999-12-13 16:37:25 +00005435 else
5436 result = PyInt_FromLong(limit);
5437 }
5438 return result;
5439}
5440#endif
5441
5442#ifdef HAVE_CONFSTR
5443static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005444#ifdef _CS_ARCHITECTURE
5445 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5446#endif
5447#ifdef _CS_HOSTNAME
5448 {"CS_HOSTNAME", _CS_HOSTNAME},
5449#endif
5450#ifdef _CS_HW_PROVIDER
5451 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5452#endif
5453#ifdef _CS_HW_SERIAL
5454 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5455#endif
5456#ifdef _CS_INITTAB_NAME
5457 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5458#endif
Fred Drakec9680921999-12-13 16:37:25 +00005459#ifdef _CS_LFS64_CFLAGS
5460 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5461#endif
5462#ifdef _CS_LFS64_LDFLAGS
5463 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5464#endif
5465#ifdef _CS_LFS64_LIBS
5466 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5467#endif
5468#ifdef _CS_LFS64_LINTFLAGS
5469 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5470#endif
5471#ifdef _CS_LFS_CFLAGS
5472 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5473#endif
5474#ifdef _CS_LFS_LDFLAGS
5475 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5476#endif
5477#ifdef _CS_LFS_LIBS
5478 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5479#endif
5480#ifdef _CS_LFS_LINTFLAGS
5481 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5482#endif
Fred Draked86ed291999-12-15 15:34:33 +00005483#ifdef _CS_MACHINE
5484 {"CS_MACHINE", _CS_MACHINE},
5485#endif
Fred Drakec9680921999-12-13 16:37:25 +00005486#ifdef _CS_PATH
5487 {"CS_PATH", _CS_PATH},
5488#endif
Fred Draked86ed291999-12-15 15:34:33 +00005489#ifdef _CS_RELEASE
5490 {"CS_RELEASE", _CS_RELEASE},
5491#endif
5492#ifdef _CS_SRPC_DOMAIN
5493 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5494#endif
5495#ifdef _CS_SYSNAME
5496 {"CS_SYSNAME", _CS_SYSNAME},
5497#endif
5498#ifdef _CS_VERSION
5499 {"CS_VERSION", _CS_VERSION},
5500#endif
Fred Drakec9680921999-12-13 16:37:25 +00005501#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5502 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5503#endif
5504#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5505 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5506#endif
5507#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5508 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5509#endif
5510#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5511 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5512#endif
5513#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5514 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5515#endif
5516#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5517 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5518#endif
5519#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5520 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5521#endif
5522#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5523 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5524#endif
5525#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5526 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5527#endif
5528#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5529 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5530#endif
5531#ifdef _CS_XBS5_LP64_OFF64_LIBS
5532 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5533#endif
5534#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5535 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5536#endif
5537#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5538 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5539#endif
5540#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5541 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5542#endif
5543#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5544 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5545#endif
5546#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5547 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5548#endif
Fred Draked86ed291999-12-15 15:34:33 +00005549#ifdef _MIPS_CS_AVAIL_PROCESSORS
5550 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5551#endif
5552#ifdef _MIPS_CS_BASE
5553 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5554#endif
5555#ifdef _MIPS_CS_HOSTID
5556 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5557#endif
5558#ifdef _MIPS_CS_HW_NAME
5559 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5560#endif
5561#ifdef _MIPS_CS_NUM_PROCESSORS
5562 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5563#endif
5564#ifdef _MIPS_CS_OSREL_MAJ
5565 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5566#endif
5567#ifdef _MIPS_CS_OSREL_MIN
5568 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5569#endif
5570#ifdef _MIPS_CS_OSREL_PATCH
5571 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5572#endif
5573#ifdef _MIPS_CS_OS_NAME
5574 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5575#endif
5576#ifdef _MIPS_CS_OS_PROVIDER
5577 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5578#endif
5579#ifdef _MIPS_CS_PROCESSORS
5580 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5581#endif
5582#ifdef _MIPS_CS_SERIAL
5583 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5584#endif
5585#ifdef _MIPS_CS_VENDOR
5586 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5587#endif
Fred Drakec9680921999-12-13 16:37:25 +00005588};
5589
5590static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005591conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005592{
5593 return conv_confname(arg, valuep, posix_constants_confstr,
5594 sizeof(posix_constants_confstr)
5595 / sizeof(struct constdef));
5596}
5597
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005598PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005599"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005601
5602static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005603posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005604{
5605 PyObject *result = NULL;
5606 int name;
5607 char buffer[64];
5608
5609 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5610 int len = confstr(name, buffer, sizeof(buffer));
5611
Fred Drakec9680921999-12-13 16:37:25 +00005612 errno = 0;
5613 if (len == 0) {
5614 if (errno != 0)
5615 posix_error();
5616 else
5617 result = PyString_FromString("");
5618 }
5619 else {
5620 if (len >= sizeof(buffer)) {
5621 result = PyString_FromStringAndSize(NULL, len);
5622 if (result != NULL)
5623 confstr(name, PyString_AS_STRING(result), len+1);
5624 }
5625 else
5626 result = PyString_FromString(buffer);
5627 }
5628 }
5629 return result;
5630}
5631#endif
5632
5633
5634#ifdef HAVE_SYSCONF
5635static struct constdef posix_constants_sysconf[] = {
5636#ifdef _SC_2_CHAR_TERM
5637 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5638#endif
5639#ifdef _SC_2_C_BIND
5640 {"SC_2_C_BIND", _SC_2_C_BIND},
5641#endif
5642#ifdef _SC_2_C_DEV
5643 {"SC_2_C_DEV", _SC_2_C_DEV},
5644#endif
5645#ifdef _SC_2_C_VERSION
5646 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5647#endif
5648#ifdef _SC_2_FORT_DEV
5649 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5650#endif
5651#ifdef _SC_2_FORT_RUN
5652 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5653#endif
5654#ifdef _SC_2_LOCALEDEF
5655 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5656#endif
5657#ifdef _SC_2_SW_DEV
5658 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5659#endif
5660#ifdef _SC_2_UPE
5661 {"SC_2_UPE", _SC_2_UPE},
5662#endif
5663#ifdef _SC_2_VERSION
5664 {"SC_2_VERSION", _SC_2_VERSION},
5665#endif
Fred Draked86ed291999-12-15 15:34:33 +00005666#ifdef _SC_ABI_ASYNCHRONOUS_IO
5667 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5668#endif
5669#ifdef _SC_ACL
5670 {"SC_ACL", _SC_ACL},
5671#endif
Fred Drakec9680921999-12-13 16:37:25 +00005672#ifdef _SC_AIO_LISTIO_MAX
5673 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5674#endif
Fred Drakec9680921999-12-13 16:37:25 +00005675#ifdef _SC_AIO_MAX
5676 {"SC_AIO_MAX", _SC_AIO_MAX},
5677#endif
5678#ifdef _SC_AIO_PRIO_DELTA_MAX
5679 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5680#endif
5681#ifdef _SC_ARG_MAX
5682 {"SC_ARG_MAX", _SC_ARG_MAX},
5683#endif
5684#ifdef _SC_ASYNCHRONOUS_IO
5685 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5686#endif
5687#ifdef _SC_ATEXIT_MAX
5688 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5689#endif
Fred Draked86ed291999-12-15 15:34:33 +00005690#ifdef _SC_AUDIT
5691 {"SC_AUDIT", _SC_AUDIT},
5692#endif
Fred Drakec9680921999-12-13 16:37:25 +00005693#ifdef _SC_AVPHYS_PAGES
5694 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5695#endif
5696#ifdef _SC_BC_BASE_MAX
5697 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5698#endif
5699#ifdef _SC_BC_DIM_MAX
5700 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5701#endif
5702#ifdef _SC_BC_SCALE_MAX
5703 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5704#endif
5705#ifdef _SC_BC_STRING_MAX
5706 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5707#endif
Fred Draked86ed291999-12-15 15:34:33 +00005708#ifdef _SC_CAP
5709 {"SC_CAP", _SC_CAP},
5710#endif
Fred Drakec9680921999-12-13 16:37:25 +00005711#ifdef _SC_CHARCLASS_NAME_MAX
5712 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5713#endif
5714#ifdef _SC_CHAR_BIT
5715 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5716#endif
5717#ifdef _SC_CHAR_MAX
5718 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5719#endif
5720#ifdef _SC_CHAR_MIN
5721 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5722#endif
5723#ifdef _SC_CHILD_MAX
5724 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5725#endif
5726#ifdef _SC_CLK_TCK
5727 {"SC_CLK_TCK", _SC_CLK_TCK},
5728#endif
5729#ifdef _SC_COHER_BLKSZ
5730 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5731#endif
5732#ifdef _SC_COLL_WEIGHTS_MAX
5733 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5734#endif
5735#ifdef _SC_DCACHE_ASSOC
5736 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5737#endif
5738#ifdef _SC_DCACHE_BLKSZ
5739 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5740#endif
5741#ifdef _SC_DCACHE_LINESZ
5742 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5743#endif
5744#ifdef _SC_DCACHE_SZ
5745 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5746#endif
5747#ifdef _SC_DCACHE_TBLKSZ
5748 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5749#endif
5750#ifdef _SC_DELAYTIMER_MAX
5751 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5752#endif
5753#ifdef _SC_EQUIV_CLASS_MAX
5754 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5755#endif
5756#ifdef _SC_EXPR_NEST_MAX
5757 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5758#endif
5759#ifdef _SC_FSYNC
5760 {"SC_FSYNC", _SC_FSYNC},
5761#endif
5762#ifdef _SC_GETGR_R_SIZE_MAX
5763 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5764#endif
5765#ifdef _SC_GETPW_R_SIZE_MAX
5766 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5767#endif
5768#ifdef _SC_ICACHE_ASSOC
5769 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5770#endif
5771#ifdef _SC_ICACHE_BLKSZ
5772 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5773#endif
5774#ifdef _SC_ICACHE_LINESZ
5775 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5776#endif
5777#ifdef _SC_ICACHE_SZ
5778 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5779#endif
Fred Draked86ed291999-12-15 15:34:33 +00005780#ifdef _SC_INF
5781 {"SC_INF", _SC_INF},
5782#endif
Fred Drakec9680921999-12-13 16:37:25 +00005783#ifdef _SC_INT_MAX
5784 {"SC_INT_MAX", _SC_INT_MAX},
5785#endif
5786#ifdef _SC_INT_MIN
5787 {"SC_INT_MIN", _SC_INT_MIN},
5788#endif
5789#ifdef _SC_IOV_MAX
5790 {"SC_IOV_MAX", _SC_IOV_MAX},
5791#endif
Fred Draked86ed291999-12-15 15:34:33 +00005792#ifdef _SC_IP_SECOPTS
5793 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5794#endif
Fred Drakec9680921999-12-13 16:37:25 +00005795#ifdef _SC_JOB_CONTROL
5796 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5797#endif
Fred Draked86ed291999-12-15 15:34:33 +00005798#ifdef _SC_KERN_POINTERS
5799 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5800#endif
5801#ifdef _SC_KERN_SIM
5802 {"SC_KERN_SIM", _SC_KERN_SIM},
5803#endif
Fred Drakec9680921999-12-13 16:37:25 +00005804#ifdef _SC_LINE_MAX
5805 {"SC_LINE_MAX", _SC_LINE_MAX},
5806#endif
5807#ifdef _SC_LOGIN_NAME_MAX
5808 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5809#endif
5810#ifdef _SC_LOGNAME_MAX
5811 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5812#endif
5813#ifdef _SC_LONG_BIT
5814 {"SC_LONG_BIT", _SC_LONG_BIT},
5815#endif
Fred Draked86ed291999-12-15 15:34:33 +00005816#ifdef _SC_MAC
5817 {"SC_MAC", _SC_MAC},
5818#endif
Fred Drakec9680921999-12-13 16:37:25 +00005819#ifdef _SC_MAPPED_FILES
5820 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5821#endif
5822#ifdef _SC_MAXPID
5823 {"SC_MAXPID", _SC_MAXPID},
5824#endif
5825#ifdef _SC_MB_LEN_MAX
5826 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5827#endif
5828#ifdef _SC_MEMLOCK
5829 {"SC_MEMLOCK", _SC_MEMLOCK},
5830#endif
5831#ifdef _SC_MEMLOCK_RANGE
5832 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5833#endif
5834#ifdef _SC_MEMORY_PROTECTION
5835 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5836#endif
5837#ifdef _SC_MESSAGE_PASSING
5838 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5839#endif
Fred Draked86ed291999-12-15 15:34:33 +00005840#ifdef _SC_MMAP_FIXED_ALIGNMENT
5841 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5842#endif
Fred Drakec9680921999-12-13 16:37:25 +00005843#ifdef _SC_MQ_OPEN_MAX
5844 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5845#endif
5846#ifdef _SC_MQ_PRIO_MAX
5847 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5848#endif
Fred Draked86ed291999-12-15 15:34:33 +00005849#ifdef _SC_NACLS_MAX
5850 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5851#endif
Fred Drakec9680921999-12-13 16:37:25 +00005852#ifdef _SC_NGROUPS_MAX
5853 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5854#endif
5855#ifdef _SC_NL_ARGMAX
5856 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5857#endif
5858#ifdef _SC_NL_LANGMAX
5859 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5860#endif
5861#ifdef _SC_NL_MSGMAX
5862 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5863#endif
5864#ifdef _SC_NL_NMAX
5865 {"SC_NL_NMAX", _SC_NL_NMAX},
5866#endif
5867#ifdef _SC_NL_SETMAX
5868 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5869#endif
5870#ifdef _SC_NL_TEXTMAX
5871 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5872#endif
5873#ifdef _SC_NPROCESSORS_CONF
5874 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5875#endif
5876#ifdef _SC_NPROCESSORS_ONLN
5877 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5878#endif
Fred Draked86ed291999-12-15 15:34:33 +00005879#ifdef _SC_NPROC_CONF
5880 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5881#endif
5882#ifdef _SC_NPROC_ONLN
5883 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5884#endif
Fred Drakec9680921999-12-13 16:37:25 +00005885#ifdef _SC_NZERO
5886 {"SC_NZERO", _SC_NZERO},
5887#endif
5888#ifdef _SC_OPEN_MAX
5889 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5890#endif
5891#ifdef _SC_PAGESIZE
5892 {"SC_PAGESIZE", _SC_PAGESIZE},
5893#endif
5894#ifdef _SC_PAGE_SIZE
5895 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5896#endif
5897#ifdef _SC_PASS_MAX
5898 {"SC_PASS_MAX", _SC_PASS_MAX},
5899#endif
5900#ifdef _SC_PHYS_PAGES
5901 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5902#endif
5903#ifdef _SC_PII
5904 {"SC_PII", _SC_PII},
5905#endif
5906#ifdef _SC_PII_INTERNET
5907 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5908#endif
5909#ifdef _SC_PII_INTERNET_DGRAM
5910 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5911#endif
5912#ifdef _SC_PII_INTERNET_STREAM
5913 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5914#endif
5915#ifdef _SC_PII_OSI
5916 {"SC_PII_OSI", _SC_PII_OSI},
5917#endif
5918#ifdef _SC_PII_OSI_CLTS
5919 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5920#endif
5921#ifdef _SC_PII_OSI_COTS
5922 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5923#endif
5924#ifdef _SC_PII_OSI_M
5925 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5926#endif
5927#ifdef _SC_PII_SOCKET
5928 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5929#endif
5930#ifdef _SC_PII_XTI
5931 {"SC_PII_XTI", _SC_PII_XTI},
5932#endif
5933#ifdef _SC_POLL
5934 {"SC_POLL", _SC_POLL},
5935#endif
5936#ifdef _SC_PRIORITIZED_IO
5937 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5938#endif
5939#ifdef _SC_PRIORITY_SCHEDULING
5940 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5941#endif
5942#ifdef _SC_REALTIME_SIGNALS
5943 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5944#endif
5945#ifdef _SC_RE_DUP_MAX
5946 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5947#endif
5948#ifdef _SC_RTSIG_MAX
5949 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5950#endif
5951#ifdef _SC_SAVED_IDS
5952 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5953#endif
5954#ifdef _SC_SCHAR_MAX
5955 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5956#endif
5957#ifdef _SC_SCHAR_MIN
5958 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5959#endif
5960#ifdef _SC_SELECT
5961 {"SC_SELECT", _SC_SELECT},
5962#endif
5963#ifdef _SC_SEMAPHORES
5964 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5965#endif
5966#ifdef _SC_SEM_NSEMS_MAX
5967 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5968#endif
5969#ifdef _SC_SEM_VALUE_MAX
5970 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
5971#endif
5972#ifdef _SC_SHARED_MEMORY_OBJECTS
5973 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
5974#endif
5975#ifdef _SC_SHRT_MAX
5976 {"SC_SHRT_MAX", _SC_SHRT_MAX},
5977#endif
5978#ifdef _SC_SHRT_MIN
5979 {"SC_SHRT_MIN", _SC_SHRT_MIN},
5980#endif
5981#ifdef _SC_SIGQUEUE_MAX
5982 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
5983#endif
5984#ifdef _SC_SIGRT_MAX
5985 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
5986#endif
5987#ifdef _SC_SIGRT_MIN
5988 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
5989#endif
Fred Draked86ed291999-12-15 15:34:33 +00005990#ifdef _SC_SOFTPOWER
5991 {"SC_SOFTPOWER", _SC_SOFTPOWER},
5992#endif
Fred Drakec9680921999-12-13 16:37:25 +00005993#ifdef _SC_SPLIT_CACHE
5994 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
5995#endif
5996#ifdef _SC_SSIZE_MAX
5997 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
5998#endif
5999#ifdef _SC_STACK_PROT
6000 {"SC_STACK_PROT", _SC_STACK_PROT},
6001#endif
6002#ifdef _SC_STREAM_MAX
6003 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6004#endif
6005#ifdef _SC_SYNCHRONIZED_IO
6006 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6007#endif
6008#ifdef _SC_THREADS
6009 {"SC_THREADS", _SC_THREADS},
6010#endif
6011#ifdef _SC_THREAD_ATTR_STACKADDR
6012 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6013#endif
6014#ifdef _SC_THREAD_ATTR_STACKSIZE
6015 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6016#endif
6017#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6018 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6019#endif
6020#ifdef _SC_THREAD_KEYS_MAX
6021 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6022#endif
6023#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6024 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6025#endif
6026#ifdef _SC_THREAD_PRIO_INHERIT
6027 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6028#endif
6029#ifdef _SC_THREAD_PRIO_PROTECT
6030 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6031#endif
6032#ifdef _SC_THREAD_PROCESS_SHARED
6033 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6034#endif
6035#ifdef _SC_THREAD_SAFE_FUNCTIONS
6036 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6037#endif
6038#ifdef _SC_THREAD_STACK_MIN
6039 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6040#endif
6041#ifdef _SC_THREAD_THREADS_MAX
6042 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6043#endif
6044#ifdef _SC_TIMERS
6045 {"SC_TIMERS", _SC_TIMERS},
6046#endif
6047#ifdef _SC_TIMER_MAX
6048 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6049#endif
6050#ifdef _SC_TTY_NAME_MAX
6051 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6052#endif
6053#ifdef _SC_TZNAME_MAX
6054 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6055#endif
6056#ifdef _SC_T_IOV_MAX
6057 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6058#endif
6059#ifdef _SC_UCHAR_MAX
6060 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6061#endif
6062#ifdef _SC_UINT_MAX
6063 {"SC_UINT_MAX", _SC_UINT_MAX},
6064#endif
6065#ifdef _SC_UIO_MAXIOV
6066 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6067#endif
6068#ifdef _SC_ULONG_MAX
6069 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6070#endif
6071#ifdef _SC_USHRT_MAX
6072 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6073#endif
6074#ifdef _SC_VERSION
6075 {"SC_VERSION", _SC_VERSION},
6076#endif
6077#ifdef _SC_WORD_BIT
6078 {"SC_WORD_BIT", _SC_WORD_BIT},
6079#endif
6080#ifdef _SC_XBS5_ILP32_OFF32
6081 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6082#endif
6083#ifdef _SC_XBS5_ILP32_OFFBIG
6084 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6085#endif
6086#ifdef _SC_XBS5_LP64_OFF64
6087 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6088#endif
6089#ifdef _SC_XBS5_LPBIG_OFFBIG
6090 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6091#endif
6092#ifdef _SC_XOPEN_CRYPT
6093 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6094#endif
6095#ifdef _SC_XOPEN_ENH_I18N
6096 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6097#endif
6098#ifdef _SC_XOPEN_LEGACY
6099 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6100#endif
6101#ifdef _SC_XOPEN_REALTIME
6102 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6103#endif
6104#ifdef _SC_XOPEN_REALTIME_THREADS
6105 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6106#endif
6107#ifdef _SC_XOPEN_SHM
6108 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6109#endif
6110#ifdef _SC_XOPEN_UNIX
6111 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6112#endif
6113#ifdef _SC_XOPEN_VERSION
6114 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6115#endif
6116#ifdef _SC_XOPEN_XCU_VERSION
6117 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6118#endif
6119#ifdef _SC_XOPEN_XPG2
6120 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6121#endif
6122#ifdef _SC_XOPEN_XPG3
6123 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6124#endif
6125#ifdef _SC_XOPEN_XPG4
6126 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6127#endif
6128};
6129
6130static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006131conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006132{
6133 return conv_confname(arg, valuep, posix_constants_sysconf,
6134 sizeof(posix_constants_sysconf)
6135 / sizeof(struct constdef));
6136}
6137
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006138PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006139"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006140Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006141
6142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006143posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006144{
6145 PyObject *result = NULL;
6146 int name;
6147
6148 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6149 int value;
6150
6151 errno = 0;
6152 value = sysconf(name);
6153 if (value == -1 && errno != 0)
6154 posix_error();
6155 else
6156 result = PyInt_FromLong(value);
6157 }
6158 return result;
6159}
6160#endif
6161
6162
Fred Drakebec628d1999-12-15 18:31:10 +00006163/* This code is used to ensure that the tables of configuration value names
6164 * are in sorted order as required by conv_confname(), and also to build the
6165 * the exported dictionaries that are used to publish information about the
6166 * names available on the host platform.
6167 *
6168 * Sorting the table at runtime ensures that the table is properly ordered
6169 * when used, even for platforms we're not able to test on. It also makes
6170 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006171 */
Fred Drakebec628d1999-12-15 18:31:10 +00006172
6173static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006174cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006175{
6176 const struct constdef *c1 =
6177 (const struct constdef *) v1;
6178 const struct constdef *c2 =
6179 (const struct constdef *) v2;
6180
6181 return strcmp(c1->name, c2->name);
6182}
6183
6184static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006185setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006186 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006187{
Fred Drakebec628d1999-12-15 18:31:10 +00006188 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006189 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006190
6191 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6192 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006193 if (d == NULL)
6194 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006195
Barry Warsaw3155db32000-04-13 15:20:40 +00006196 for (i=0; i < tablesize; ++i) {
6197 PyObject *o = PyInt_FromLong(table[i].value);
6198 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6199 Py_XDECREF(o);
6200 Py_DECREF(d);
6201 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006202 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006203 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006204 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006205 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006206}
6207
Fred Drakebec628d1999-12-15 18:31:10 +00006208/* Return -1 on failure, 0 on success. */
6209static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006210setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006211{
6212#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006213 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006214 sizeof(posix_constants_pathconf)
6215 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006216 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006217 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006218#endif
6219#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006220 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006221 sizeof(posix_constants_confstr)
6222 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006223 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006224 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006225#endif
6226#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006227 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006228 sizeof(posix_constants_sysconf)
6229 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006230 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006231 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006232#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006233 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006234}
Fred Draked86ed291999-12-15 15:34:33 +00006235
6236
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006237PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006238"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006239Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006240in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006241
6242static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006243posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006244{
6245 if (!PyArg_ParseTuple(args, ":abort"))
6246 return NULL;
6247 abort();
6248 /*NOTREACHED*/
6249 Py_FatalError("abort() called from Python code didn't abort!");
6250 return NULL;
6251}
Fred Drakebec628d1999-12-15 18:31:10 +00006252
Tim Petersf58a7aa2000-09-22 10:05:54 +00006253#ifdef MS_WIN32
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006254PyDoc_STRVAR(win32_startfile__doc__,
6255"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006256\n\
6257This acts like double-clicking the file in Explorer, or giving the file\n\
6258name as an argument to the DOS \"start\" command: the file is opened\n\
6259with whatever application (if any) its extension is associated.\n\
6260\n\
6261startfile returns as soon as the associated application is launched.\n\
6262There is no option to wait for the application to close, and no way\n\
6263to retrieve the application's exit status.\n\
6264\n\
6265The filepath is relative to the current directory. If you want to use\n\
6266an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006267the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006268
6269static PyObject *
6270win32_startfile(PyObject *self, PyObject *args)
6271{
6272 char *filepath;
6273 HINSTANCE rc;
6274 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6275 return NULL;
6276 Py_BEGIN_ALLOW_THREADS
6277 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6278 Py_END_ALLOW_THREADS
6279 if (rc <= (HINSTANCE)32)
6280 return win32_error("startfile", filepath);
6281 Py_INCREF(Py_None);
6282 return Py_None;
6283}
6284#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006285
6286static PyMethodDef posix_methods[] = {
6287 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6288#ifdef HAVE_TTYNAME
6289 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6290#endif
6291 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6292 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006293#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006294 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006295#endif /* HAVE_CHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006296#ifdef HAVE_CHROOT
6297 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6298#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006299#ifdef HAVE_CTERMID
6300 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6301#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006302#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006303 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006304#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006305#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006306 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006307#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006308 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6309 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6310 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006311#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006312 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006313#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006314#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006315 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006316#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006317 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6318 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6319 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006320#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006321 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006322#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006323#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006324 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006325#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006326 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006327#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006328 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006329#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006330 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6331 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6332 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006333#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006334 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006335#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006336 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006337#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006338 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6339 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006340#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006341#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006342 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6343 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006344#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006345#ifdef HAVE_FORK1
6346 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6347#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006348#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006349 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006350#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006351#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006352 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006353#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006354#ifdef HAVE_FORKPTY
6355 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6356#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006357#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006358 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006359#endif /* HAVE_GETEGID */
6360#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006361 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006362#endif /* HAVE_GETEUID */
6363#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006364 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006365#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006366#ifdef HAVE_GETGROUPS
6367 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6368#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006369 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006370#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006371 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006372#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006373#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006374 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006375#endif /* HAVE_GETPPID */
6376#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006377 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006378#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006379#ifdef HAVE_GETLOGIN
6380 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6381#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006382#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006383 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006384#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006385#ifdef HAVE_KILLPG
6386 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6387#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006388#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006389 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006390#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006391#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006392 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006393#ifdef MS_WIN32
6394 {"popen2", win32_popen2, METH_VARARGS},
6395 {"popen3", win32_popen3, METH_VARARGS},
6396 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006397 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006398#else
6399#if defined(PYOS_OS2) && defined(PYCC_GCC)
6400 {"popen2", os2emx_popen2, METH_VARARGS},
6401 {"popen3", os2emx_popen3, METH_VARARGS},
6402 {"popen4", os2emx_popen4, METH_VARARGS},
6403#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006404#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006405#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006406#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006407 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006408#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006409#ifdef HAVE_SETEUID
6410 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6411#endif /* HAVE_SETEUID */
6412#ifdef HAVE_SETEGID
6413 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6414#endif /* HAVE_SETEGID */
6415#ifdef HAVE_SETREUID
6416 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6417#endif /* HAVE_SETREUID */
6418#ifdef HAVE_SETREGID
6419 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6420#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006421#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006422 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006423#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006424#ifdef HAVE_SETGROUPS
6425 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6426#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006427#ifdef HAVE_GETPGID
6428 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6429#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006430#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006431 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006432#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006433#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006434 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006435#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006436#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006437 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006438#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006439#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006440 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006441#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006442#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006443 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006444#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006445#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006446 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006447#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006448#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006449 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006450#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006451 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6452 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6453 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6454 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6455 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6456 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6457 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6458 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6459 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006460 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006461#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006462 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006463#endif
6464#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006465 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006466#endif
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006467#ifdef HAVE_MKNOD
6468 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6469#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006470#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006471 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006472#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006473#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006474 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006475#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006476#ifdef HAVE_UNSETENV
6477 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6478#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006479#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006480 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006481#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006482#ifdef HAVE_FCHDIR
6483 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6484#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006485#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006486 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006487#endif
6488#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006489 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006490#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006491#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006492#ifdef WCOREDUMP
6493 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6494#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006495#ifdef WIFCONTINUED
6496 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6497#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006498#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006499 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006500#endif /* WIFSTOPPED */
6501#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006502 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006503#endif /* WIFSIGNALED */
6504#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006505 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006506#endif /* WIFEXITED */
6507#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006508 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006509#endif /* WEXITSTATUS */
6510#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006511 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006512#endif /* WTERMSIG */
6513#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006514 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006515#endif /* WSTOPSIG */
6516#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006517#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006518 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006519#endif
6520#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006521 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006522#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006523#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006524 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6525#endif
6526#ifdef HAVE_TEMPNAM
6527 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6528#endif
6529#ifdef HAVE_TMPNAM
6530 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6531#endif
Fred Drakec9680921999-12-13 16:37:25 +00006532#ifdef HAVE_CONFSTR
6533 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6534#endif
6535#ifdef HAVE_SYSCONF
6536 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6537#endif
6538#ifdef HAVE_FPATHCONF
6539 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6540#endif
6541#ifdef HAVE_PATHCONF
6542 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6543#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006544 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +00006545#ifdef MS_WIN32
6546 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6547#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006548 {NULL, NULL} /* Sentinel */
6549};
6550
6551
Barry Warsaw4a342091996-12-19 23:50:02 +00006552static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006553ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006554{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006555 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006556}
6557
Guido van Rossumd48f2521997-12-05 22:19:34 +00006558#if defined(PYOS_OS2)
6559/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006560static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006561{
6562 APIRET rc;
6563 ULONG values[QSV_MAX+1];
6564 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006565 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006566
6567 Py_BEGIN_ALLOW_THREADS
6568 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6569 Py_END_ALLOW_THREADS
6570
6571 if (rc != NO_ERROR) {
6572 os2_error(rc);
6573 return -1;
6574 }
6575
Fred Drake4d1e64b2002-04-15 19:40:07 +00006576 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6577 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6578 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6579 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6580 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6581 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6582 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006583
6584 switch (values[QSV_VERSION_MINOR]) {
6585 case 0: ver = "2.00"; break;
6586 case 10: ver = "2.10"; break;
6587 case 11: ver = "2.11"; break;
6588 case 30: ver = "3.00"; break;
6589 case 40: ver = "4.00"; break;
6590 case 50: ver = "5.00"; break;
6591 default:
Tim Peters885d4572001-11-28 20:27:42 +00006592 PyOS_snprintf(tmp, sizeof(tmp),
6593 "%d-%d", values[QSV_VERSION_MAJOR],
6594 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006595 ver = &tmp[0];
6596 }
6597
6598 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006599 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006600 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006601
6602 /* Add Indicator of Which Drive was Used to Boot the System */
6603 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6604 tmp[1] = ':';
6605 tmp[2] = '\0';
6606
Fred Drake4d1e64b2002-04-15 19:40:07 +00006607 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006608}
6609#endif
6610
Barry Warsaw4a342091996-12-19 23:50:02 +00006611static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006612all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006613{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006614#ifdef F_OK
6615 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006616#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006617#ifdef R_OK
6618 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006619#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006620#ifdef W_OK
6621 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006622#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006623#ifdef X_OK
6624 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006625#endif
Fred Drakec9680921999-12-13 16:37:25 +00006626#ifdef NGROUPS_MAX
6627 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6628#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006629#ifdef TMP_MAX
6630 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6631#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006632#ifdef WCONTINUED
6633 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6634#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006635#ifdef WNOHANG
6636 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006637#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006638#ifdef WUNTRACED
6639 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6640#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006641#ifdef O_RDONLY
6642 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6643#endif
6644#ifdef O_WRONLY
6645 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6646#endif
6647#ifdef O_RDWR
6648 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6649#endif
6650#ifdef O_NDELAY
6651 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6652#endif
6653#ifdef O_NONBLOCK
6654 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6655#endif
6656#ifdef O_APPEND
6657 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6658#endif
6659#ifdef O_DSYNC
6660 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6661#endif
6662#ifdef O_RSYNC
6663 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6664#endif
6665#ifdef O_SYNC
6666 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6667#endif
6668#ifdef O_NOCTTY
6669 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6670#endif
6671#ifdef O_CREAT
6672 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6673#endif
6674#ifdef O_EXCL
6675 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6676#endif
6677#ifdef O_TRUNC
6678 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6679#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006680#ifdef O_BINARY
6681 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6682#endif
6683#ifdef O_TEXT
6684 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6685#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006686#ifdef O_LARGEFILE
6687 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6688#endif
6689
Tim Peters5aa91602002-01-30 05:46:57 +00006690/* MS Windows */
6691#ifdef O_NOINHERIT
6692 /* Don't inherit in child processes. */
6693 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6694#endif
6695#ifdef _O_SHORT_LIVED
6696 /* Optimize for short life (keep in memory). */
6697 /* MS forgot to define this one with a non-underscore form too. */
6698 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6699#endif
6700#ifdef O_TEMPORARY
6701 /* Automatically delete when last handle is closed. */
6702 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6703#endif
6704#ifdef O_RANDOM
6705 /* Optimize for random access. */
6706 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6707#endif
6708#ifdef O_SEQUENTIAL
6709 /* Optimize for sequential access. */
6710 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6711#endif
6712
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006713/* GNU extensions. */
6714#ifdef O_DIRECT
6715 /* Direct disk access. */
6716 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6717#endif
6718#ifdef O_DIRECTORY
6719 /* Must be a directory. */
6720 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6721#endif
6722#ifdef O_NOFOLLOW
6723 /* Do not follow links. */
6724 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6725#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006726
Guido van Rossum246bc171999-02-01 23:54:31 +00006727#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006728#if defined(PYOS_OS2) && defined(PYCC_GCC)
6729 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6730 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6731 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6732 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6733 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6734 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6735 if (ins(d, "P_PM", (long)P_PM)) return -1;
6736 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6737 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6738 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6739 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6740 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6741 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6742 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6743 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6744 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6745 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6746 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6747 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6748 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6749#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006750 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6751 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6752 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6753 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6754 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006755#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006756#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006757
Guido van Rossumd48f2521997-12-05 22:19:34 +00006758#if defined(PYOS_OS2)
6759 if (insertvalues(d)) return -1;
6760#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006761 return 0;
6762}
6763
6764
Tim Peters5aa91602002-01-30 05:46:57 +00006765#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006766#define INITFUNC initnt
6767#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006768
6769#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006770#define INITFUNC initos2
6771#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006772
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006773#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006774#define INITFUNC initposix
6775#define MODNAME "posix"
6776#endif
6777
Guido van Rossum3886bb61998-12-04 18:50:17 +00006778DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006779INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006780{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006781 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006782
Fred Drake4d1e64b2002-04-15 19:40:07 +00006783 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006784 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006785 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006786
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006787 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006788 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006789 Py_XINCREF(v);
6790 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006791 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006792 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006793
Fred Drake4d1e64b2002-04-15 19:40:07 +00006794 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006795 return;
6796
Fred Drake4d1e64b2002-04-15 19:40:07 +00006797 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006798 return;
6799
Fred Drake4d1e64b2002-04-15 19:40:07 +00006800 Py_INCREF(PyExc_OSError);
6801 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006802
Guido van Rossumb3d39562000-01-31 18:41:26 +00006803#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006804 if (posix_putenv_garbage == NULL)
6805 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006806#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006807
Guido van Rossum14648392001-12-08 18:02:58 +00006808 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006809 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006810 Py_INCREF((PyObject*) &StatResultType);
6811 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006812
Guido van Rossum14648392001-12-08 18:02:58 +00006813 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006814 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006815 Py_INCREF((PyObject*) &StatVFSResultType);
6816 PyModule_AddObject(m, "statvfs_result",
6817 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006818}