blob: f0e3f0d86c67ee8088589614cab8e6798ee5d861 [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
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' 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
Guido van Rossuma1065681999-01-25 23:20:23 +000085#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000086#define HAVE_EXECV 1
87#define HAVE_PIPE 1
88#define HAVE_POPEN 1
89#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +000090#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000091#else
92#if defined(PYOS_OS2) && defined(PYCC_GCC)
93/* Everything needed is defined in PC/os2emx/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#else /* all other compilers */
95/* Unix functions that the configure script doesn't check for */
96#define HAVE_EXECV 1
97#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +000098#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
99#define HAVE_FORK1 1
100#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_GETCWD 1
102#define HAVE_GETEGID 1
103#define HAVE_GETEUID 1
104#define HAVE_GETGID 1
105#define HAVE_GETPPID 1
106#define HAVE_GETUID 1
107#define HAVE_KILL 1
108#define HAVE_OPENDIR 1
109#define HAVE_PIPE 1
110#define HAVE_POPEN 1
111#define HAVE_SYSTEM 1
112#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000113#define HAVE_TTYNAME 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000114#endif /* PYOS_OS2 && PYCC_GCC */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000115#endif /* _MSC_VER */
116#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000117#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000118#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000119
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000121
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000122#if defined(sun) && !defined(__SVR4)
123/* SunOS 4.1.4 doesn't have prototypes for these: */
124extern int rename(const char *, const char *);
125extern int pclose(FILE *);
126extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000127extern int fsync(int);
128extern int lstat(const char *, struct stat *);
129extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000130#endif
131
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000132#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000134extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000135#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000136#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000137extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000138#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000139extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#endif
142#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int chdir(char *);
144extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000145#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000146extern int chdir(const char *);
147extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000149#ifdef __BORLANDC__
150extern int chmod(const char *, int);
151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000153#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int chown(const char *, uid_t, gid_t);
155extern char *getcwd(char *, int);
156extern char *strerror(int);
157extern int link(const char *, const char *);
158extern int rename(const char *, const char *);
159extern int stat(const char *, struct stat *);
160extern int unlink(const char *);
161extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000164#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000165#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000166extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000167#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000169
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172#ifdef HAVE_UTIME_H
173#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000174#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000175
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000176#ifdef HAVE_SYS_UTIME_H
177#include <sys/utime.h>
178#define HAVE_UTIME_H /* pretend we do for the rest of this file */
179#endif /* HAVE_SYS_UTIME_H */
180
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181#ifdef HAVE_SYS_TIMES_H
182#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000183#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184
185#ifdef HAVE_SYS_PARAM_H
186#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000187#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000188
189#ifdef HAVE_SYS_UTSNAME_H
190#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000191#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000193#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000195#define NAMLEN(dirent) strlen((dirent)->d_name)
196#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000197#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000198#include <direct.h>
199#define NAMLEN(dirent) strlen((dirent)->d_name)
200#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000202#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#endif
207#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000209#endif
210#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#include <direct.h>
217#include <io.h>
218#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000219#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000220#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000222#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000223#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000224#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000225#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226
Guido van Rossumd48f2521997-12-05 22:19:34 +0000227#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230
Tim Petersbc2e10e2002-03-03 23:17:02 +0000231#ifndef MAXPATHLEN
232#define MAXPATHLEN 1024
233#endif /* MAXPATHLEN */
234
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000235#ifdef UNION_WAIT
236/* Emulate some macros on systems that have a union instead of macros */
237
238#ifndef WIFEXITED
239#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
240#endif
241
242#ifndef WEXITSTATUS
243#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
244#endif
245
246#ifndef WTERMSIG
247#define WTERMSIG(u_wait) ((u_wait).w_termsig)
248#endif
249
250#endif /* UNION_WAIT */
251
Greg Wardb48bc172000-03-01 21:51:56 +0000252/* Don't use the "_r" form if we don't need it (also, won't have a
253 prototype for it, at least on Solaris -- maybe others as well?). */
254#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
255#define USE_CTERMID_R
256#endif
257
258#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
259#define USE_TMPNAM_R
260#endif
261
Fred Drake699f3522000-06-29 21:12:41 +0000262/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000263#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000264#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000265# define STAT _stati64
266# define FSTAT _fstati64
267# define STRUCT_STAT struct _stati64
268#else
269# define STAT stat
270# define FSTAT fstat
271# define STRUCT_STAT struct stat
272#endif
273
Neal Norwitz3d949422002-04-20 13:46:43 +0000274#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
275#include <sys/mkdev.h>
276#endif
Fred Drake699f3522000-06-29 21:12:41 +0000277
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000279#ifdef WITH_NEXT_FRAMEWORK
280/* On Darwin/MacOSX a shared library or framework has no access to
281** environ directly, we must obtain it with _NSGetEnviron().
282*/
283#include <crt_externs.h>
284static char **environ;
285#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000286extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000287#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288
Barry Warsaw53699e91996-12-10 23:23:01 +0000289static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000290convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291{
Barry Warsaw53699e91996-12-10 23:23:01 +0000292 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000293 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000294 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295 if (d == NULL)
296 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000297#ifdef WITH_NEXT_FRAMEWORK
298 if (environ == NULL)
299 environ = *_NSGetEnviron();
300#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301 if (environ == NULL)
302 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000303 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000305 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000306 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307 char *p = strchr(*e, '=');
308 if (p == NULL)
309 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000310 k = PyString_FromStringAndSize(*e, (int)(p-*e));
311 if (k == NULL) {
312 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000314 }
315 v = PyString_FromString(p+1);
316 if (v == NULL) {
317 PyErr_Clear();
318 Py_DECREF(k);
319 continue;
320 }
321 if (PyDict_GetItem(d, k) == NULL) {
322 if (PyDict_SetItem(d, k, v) != 0)
323 PyErr_Clear();
324 }
325 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000326 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000327 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000328#if defined(PYOS_OS2)
329 {
330 APIRET rc;
331 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
332
333 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000334 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000335 PyObject *v = PyString_FromString(buffer);
336 PyDict_SetItemString(d, "BEGINLIBPATH", v);
337 Py_DECREF(v);
338 }
339 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
340 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
341 PyObject *v = PyString_FromString(buffer);
342 PyDict_SetItemString(d, "ENDLIBPATH", v);
343 Py_DECREF(v);
344 }
345 }
346#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347 return d;
348}
349
350
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351/* Set a POSIX-specific error from errno, and return NULL */
352
Barry Warsawd58d7641998-07-23 16:14:40 +0000353static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000354posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000355{
Barry Warsawca74da41999-02-09 19:31:45 +0000356 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357}
Barry Warsawd58d7641998-07-23 16:14:40 +0000358static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000359posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000360{
Barry Warsawca74da41999-02-09 19:31:45 +0000361 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000362}
363
Mark Hammondef8b6542001-05-13 08:04:26 +0000364static PyObject *
365posix_error_with_allocated_filename(char* name)
366{
367 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
368 PyMem_Free(name);
369 return rc;
370}
371
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000372#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000373static PyObject *
374win32_error(char* function, char* filename)
375{
Mark Hammond33a6da92000-08-15 00:46:38 +0000376 /* XXX We should pass the function name along in the future.
377 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000378 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000379 Windows error object, which is non-trivial.
380 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000381 errno = GetLastError();
382 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000383 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000384 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000385 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000386}
387#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000388
Guido van Rossumd48f2521997-12-05 22:19:34 +0000389#if defined(PYOS_OS2)
390/**********************************************************************
391 * Helper Function to Trim and Format OS/2 Messages
392 **********************************************************************/
393 static void
394os2_formatmsg(char *msgbuf, int msglen, char *reason)
395{
396 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
397
398 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
399 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
400
401 while (lastc > msgbuf && isspace(*lastc))
402 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
403 }
404
405 /* Add Optional Reason Text */
406 if (reason) {
407 strcat(msgbuf, " : ");
408 strcat(msgbuf, reason);
409 }
410}
411
412/**********************************************************************
413 * Decode an OS/2 Operating System Error Code
414 *
415 * A convenience function to lookup an OS/2 error code and return a
416 * text message we can use to raise a Python exception.
417 *
418 * Notes:
419 * The messages for errors returned from the OS/2 kernel reside in
420 * the file OSO001.MSG in the \OS2 directory hierarchy.
421 *
422 **********************************************************************/
423 static char *
424os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
425{
426 APIRET rc;
427 ULONG msglen;
428
429 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
430 Py_BEGIN_ALLOW_THREADS
431 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
432 errorcode, "oso001.msg", &msglen);
433 Py_END_ALLOW_THREADS
434
435 if (rc == NO_ERROR)
436 os2_formatmsg(msgbuf, msglen, reason);
437 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000438 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000439 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000440
441 return msgbuf;
442}
443
444/* Set an OS/2-specific error and return NULL. OS/2 kernel
445 errors are not in a global variable e.g. 'errno' nor are
446 they congruent with posix error numbers. */
447
448static PyObject * os2_error(int code)
449{
450 char text[1024];
451 PyObject *v;
452
453 os2_strerror(text, sizeof(text), code, "");
454
455 v = Py_BuildValue("(is)", code, text);
456 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000457 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000458 Py_DECREF(v);
459 }
460 return NULL; /* Signal to Python that an Exception is Pending */
461}
462
463#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000464
465/* POSIX generic methods */
466
Barry Warsaw53699e91996-12-10 23:23:01 +0000467static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000468posix_fildes(PyObject *fdobj, int (*func)(int))
469{
470 int fd;
471 int res;
472 fd = PyObject_AsFileDescriptor(fdobj);
473 if (fd < 0)
474 return NULL;
475 Py_BEGIN_ALLOW_THREADS
476 res = (*func)(fd);
477 Py_END_ALLOW_THREADS
478 if (res < 0)
479 return posix_error();
480 Py_INCREF(Py_None);
481 return Py_None;
482}
Guido van Rossum21142a01999-01-08 21:05:37 +0000483
484static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000485posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000486{
Mark Hammondef8b6542001-05-13 08:04:26 +0000487 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000488 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000489 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000490 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000491 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000492 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000493 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000494 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000495 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000496 return posix_error_with_allocated_filename(path1);
497 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000498 Py_INCREF(Py_None);
499 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000500}
501
Barry Warsaw53699e91996-12-10 23:23:01 +0000502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000503posix_2str(PyObject *args, char *format,
504 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000505{
Mark Hammondef8b6542001-05-13 08:04:26 +0000506 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000507 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000508 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000509 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000510 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000512 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000513 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000514 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000515 PyMem_Free(path1);
516 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000517 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000518 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000519 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000520 Py_INCREF(Py_None);
521 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000522}
523
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000524PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000525"stat_result: Result from stat or lstat.\n\n\
526This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000527 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000528or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
529\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000530Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000531they are available as attributes only.\n\
532\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000533See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000534
535static PyStructSequence_Field stat_result_fields[] = {
536 {"st_mode", "protection bits"},
537 {"st_ino", "inode"},
538 {"st_dev", "device"},
539 {"st_nlink", "number of hard links"},
540 {"st_uid", "user ID of owner"},
541 {"st_gid", "group ID of owner"},
542 {"st_size", "total size, in bytes"},
543 {"st_atime", "time of last access"},
544 {"st_mtime", "time of last modification"},
545 {"st_ctime", "time of last change"},
546#ifdef HAVE_ST_BLKSIZE
547 {"st_blksize", "blocksize for filesystem I/O"},
548#endif
549#ifdef HAVE_ST_BLOCKS
550 {"st_blocks", "number of blocks allocated"},
551#endif
552#ifdef HAVE_ST_RDEV
553 {"st_rdev", "device type (if inode device)"},
554#endif
555 {0}
556};
557
558#ifdef HAVE_ST_BLKSIZE
559#define ST_BLKSIZE_IDX 10
560#else
561#define ST_BLKSIZE_IDX 9
562#endif
563
564#ifdef HAVE_ST_BLOCKS
565#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
566#else
567#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
568#endif
569
570#ifdef HAVE_ST_RDEV
571#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
572#else
573#define ST_RDEV_IDX ST_BLOCKS_IDX
574#endif
575
576static PyStructSequence_Desc stat_result_desc = {
577 "stat_result", /* name */
578 stat_result__doc__, /* doc */
579 stat_result_fields,
580 10
581};
582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000583PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000584"statvfs_result: Result from statvfs or fstatvfs.\n\n\
585This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000586 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000587or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000588\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000589See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000590
591static PyStructSequence_Field statvfs_result_fields[] = {
592 {"f_bsize", },
593 {"f_frsize", },
594 {"f_blocks", },
595 {"f_bfree", },
596 {"f_bavail", },
597 {"f_files", },
598 {"f_ffree", },
599 {"f_favail", },
600 {"f_flag", },
601 {"f_namemax",},
602 {0}
603};
604
605static PyStructSequence_Desc statvfs_result_desc = {
606 "statvfs_result", /* name */
607 statvfs_result__doc__, /* doc */
608 statvfs_result_fields,
609 10
610};
611
612static PyTypeObject StatResultType;
613static PyTypeObject StatVFSResultType;
614
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000615static void
616fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
617{
618 PyObject *val;
Martin v. Löwisa32c9942002-09-09 16:17:47 +0000619 val = PyFloat_FromDouble(sec + 1e-9*nsec);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000620 PyStructSequence_SET_ITEM(v, index, val);
621}
622
Tim Peters5aa91602002-01-30 05:46:57 +0000623/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000624 (used by posix_stat() and posix_fstat()) */
625static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000626_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000627{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000628 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000629 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000630 if (v == NULL)
631 return NULL;
632
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000633 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000634#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000635 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000636 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000637#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000638 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000639#endif
640#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000641 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000642 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000643#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000644 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000645#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000646 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
647 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
648 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000649#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000650 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000651 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000652#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000653 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000654#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000655
656#ifdef HAVE_STAT_TV_NSEC
657 ansec = st.st_atim.tv_nsec;
658 mnsec = st.st_mtim.tv_nsec;
659 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000660#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000661 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000662#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000663 fill_time(v, 7, st.st_atime, ansec);
664 fill_time(v, 8, st.st_mtime, mnsec);
665 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000666
667#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000668 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000669 PyInt_FromLong((long)st.st_blksize));
670#endif
671#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000672 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000673 PyInt_FromLong((long)st.st_blocks));
674#endif
675#ifdef HAVE_ST_RDEV
676 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
677 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000678#endif
679
680 if (PyErr_Occurred()) {
681 Py_DECREF(v);
682 return NULL;
683 }
684
685 return v;
686}
687
Barry Warsaw53699e91996-12-10 23:23:01 +0000688static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000689posix_do_stat(PyObject *self, PyObject *args, char *format,
690 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000691{
Fred Drake699f3522000-06-29 21:12:41 +0000692 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000693 char *path = NULL; /* pass this to stat; do not free() it */
694 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000695 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000696
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000697#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000698 int pathlen;
699 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000700#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000701
Tim Peters5aa91602002-01-30 05:46:57 +0000702 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000703 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000704 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000705 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000706
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000707#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000708 pathlen = strlen(path);
709 /* the library call can blow up if the file name is too long! */
710 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000711 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000712 errno = ENAMETOOLONG;
713 return posix_error();
714 }
715
Tim Peters500bd032001-12-19 19:05:01 +0000716 /* Remove trailing slash or backslash, unless it's the current
717 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
718 */
719 if (pathlen > 0 &&
720 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
721 /* It does end with a slash -- exempt the root drive cases. */
722 /* XXX UNC root drives should also be exempted? */
723 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
724 /* leave it alone */;
725 else {
726 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000727 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000728 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000729 path = pathcopy;
730 }
731 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000732#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000733
Barry Warsaw53699e91996-12-10 23:23:01 +0000734 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000735 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000736 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000737 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000738 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000739
Tim Peters500bd032001-12-19 19:05:01 +0000740 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000741 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000742}
743
744
745/* POSIX methods */
746
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000747PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000748"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000749Use the real uid/gid to test for access to a path. Note that most\n\
750operations will use the effective uid/gid, therefore this routine can\n\
751be used in a suid/sgid environment to test if the invoking user has the\n\
752specified access to the path. The mode argument can be F_OK to test\n\
753existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000754
755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000756posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000757{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000758 char *path;
759 int mode;
760 int res;
761
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000762 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000763 return NULL;
764 Py_BEGIN_ALLOW_THREADS
765 res = access(path, mode);
766 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +0000767 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000768}
769
Guido van Rossumd371ff11999-01-25 16:12:23 +0000770#ifndef F_OK
771#define F_OK 0
772#endif
773#ifndef R_OK
774#define R_OK 4
775#endif
776#ifndef W_OK
777#define W_OK 2
778#endif
779#ifndef X_OK
780#define X_OK 1
781#endif
782
783#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000784PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000785"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000786Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000787
788static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000789posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000790{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000791 int id;
792 char *ret;
793
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000794 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000795 return NULL;
796
Guido van Rossum94f6f721999-01-06 18:42:14 +0000797 ret = ttyname(id);
798 if (ret == NULL)
799 return(posix_error());
800 return(PyString_FromString(ret));
801}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000802#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000803
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000804#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000805PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000806"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000807Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000808
809static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000810posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000811{
812 char *ret;
813 char buffer[L_ctermid];
814
815 if (!PyArg_ParseTuple(args, ":ctermid"))
816 return NULL;
817
Greg Wardb48bc172000-03-01 21:51:56 +0000818#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000819 ret = ctermid_r(buffer);
820#else
821 ret = ctermid(buffer);
822#endif
823 if (ret == NULL)
824 return(posix_error());
825 return(PyString_FromString(buffer));
826}
827#endif
828
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000829PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000830"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000831Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000832
Barry Warsaw53699e91996-12-10 23:23:01 +0000833static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000834posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000835{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000836#if defined(PYOS_OS2) && defined(PYCC_GCC)
837 return posix_1str(args, "et:chdir", _chdir2);
838#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000839 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000840#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000841}
842
Fred Drake4d1e64b2002-04-15 19:40:07 +0000843#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000844PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000845"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +0000846Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000847opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +0000848
849static PyObject *
850posix_fchdir(PyObject *self, PyObject *fdobj)
851{
852 return posix_fildes(fdobj, fchdir);
853}
854#endif /* HAVE_FCHDIR */
855
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000856
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000857PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000858"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000859Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000860
Barry Warsaw53699e91996-12-10 23:23:01 +0000861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000862posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000863{
Mark Hammondef8b6542001-05-13 08:04:26 +0000864 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000865 int i;
866 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000867 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000868 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000869 return NULL;
870 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000871 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000872 Py_END_ALLOW_THREADS
873 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000874 return posix_error_with_allocated_filename(path);
875 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000876 Py_INCREF(Py_None);
877 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000878}
879
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000880
Martin v. Löwis244edc82001-10-04 22:44:26 +0000881#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000882PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000883"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000884Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +0000885
886static PyObject *
887posix_chroot(PyObject *self, PyObject *args)
888{
889 return posix_1str(args, "et:chroot", chroot);
890}
891#endif
892
Guido van Rossum21142a01999-01-08 21:05:37 +0000893#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000894PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000895"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000896force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000897
898static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000899posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000900{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000901 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000902}
903#endif /* HAVE_FSYNC */
904
905#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000906
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000907#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000908extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
909#endif
910
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000911PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000912"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +0000913force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000914 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000915
916static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000917posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000918{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000919 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000920}
921#endif /* HAVE_FDATASYNC */
922
923
Fredrik Lundh10723342000-07-10 16:38:09 +0000924#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000925PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000926"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000927Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000928
Barry Warsaw53699e91996-12-10 23:23:01 +0000929static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000930posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000931{
Mark Hammondef8b6542001-05-13 08:04:26 +0000932 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000933 int uid, gid;
934 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000935 if (!PyArg_ParseTuple(args, "etii:chown",
936 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000937 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000938 return NULL;
939 Py_BEGIN_ALLOW_THREADS
940 res = chown(path, (uid_t) uid, (gid_t) gid);
941 Py_END_ALLOW_THREADS
942 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000943 return posix_error_with_allocated_filename(path);
944 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000945 Py_INCREF(Py_None);
946 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000947}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000948#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000949
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +0000950#ifdef HAVE_LCHOWN
951PyDoc_STRVAR(posix_lchown__doc__,
952"lchown(path, uid, gid)\n\n\
953Change the owner and group id of path to the numeric uid and gid.\n\
954This function will not follow symbolic links.");
955
956static PyObject *
957posix_lchown(PyObject *self, PyObject *args)
958{
959 char *path = NULL;
960 int uid, gid;
961 int res;
962 if (!PyArg_ParseTuple(args, "etii:lchown",
963 Py_FileSystemDefaultEncoding, &path,
964 &uid, &gid))
965 return NULL;
966 Py_BEGIN_ALLOW_THREADS
967 res = lchown(path, (uid_t) uid, (gid_t) gid);
968 Py_END_ALLOW_THREADS
969 if (res < 0)
970 return posix_error_with_allocated_filename(path);
971 PyMem_Free(path);
972 Py_INCREF(Py_None);
973 return Py_None;
974}
975#endif /* HAVE_LCHOWN */
976
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000977
Guido van Rossum36bc6801995-06-14 22:54:23 +0000978#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000979PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000980"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000981Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000982
Barry Warsaw53699e91996-12-10 23:23:01 +0000983static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000984posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000985{
986 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000987 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000988 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000989 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000990 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000991#if defined(PYOS_OS2) && defined(PYCC_GCC)
992 res = _getcwd2(buf, sizeof buf);
993#else
Guido van Rossumff4949e1992-08-05 19:58:53 +0000994 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000995#endif
Barry Warsaw53699e91996-12-10 23:23:01 +0000996 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000997 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000998 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000999 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001000}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001001#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001002
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001003
Guido van Rossumb6775db1994-08-01 11:34:53 +00001004#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001005PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001006"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001007Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001008
Barry Warsaw53699e91996-12-10 23:23:01 +00001009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001010posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001011{
Mark Hammondef8b6542001-05-13 08:04:26 +00001012 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001013}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001014#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001015
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001016
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001017PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001018"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001019Return a list containing the names of the entries in the directory.\n\
1020\n\
1021 path: path of directory to list\n\
1022\n\
1023The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001024entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001025
Barry Warsaw53699e91996-12-10 23:23:01 +00001026static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001027posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001028{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001029 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001030 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001031#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001032
Barry Warsaw53699e91996-12-10 23:23:01 +00001033 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001034 HANDLE hFindFile;
1035 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001036 /* MAX_PATH characters could mean a bigger encoded string */
1037 char namebuf[MAX_PATH*2+5];
1038 char *bufptr = namebuf;
1039 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001040
Tim Peters5aa91602002-01-30 05:46:57 +00001041 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001042 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001043 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001044 if (len > 0) {
1045 char ch = namebuf[len-1];
1046 if (ch != SEP && ch != ALTSEP && ch != ':')
1047 namebuf[len++] = '/';
1048 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001049 strcpy(namebuf + len, "*.*");
1050
Barry Warsaw53699e91996-12-10 23:23:01 +00001051 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001052 return NULL;
1053
1054 hFindFile = FindFirstFile(namebuf, &FileData);
1055 if (hFindFile == INVALID_HANDLE_VALUE) {
1056 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001057 if (errno == ERROR_FILE_NOT_FOUND)
1058 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001059 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001060 }
1061 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001062 if (FileData.cFileName[0] == '.' &&
1063 (FileData.cFileName[1] == '\0' ||
1064 FileData.cFileName[1] == '.' &&
1065 FileData.cFileName[2] == '\0'))
1066 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001067 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001068 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001069 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001070 d = NULL;
1071 break;
1072 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001073 if (PyList_Append(d, v) != 0) {
1074 Py_DECREF(v);
1075 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001076 d = NULL;
1077 break;
1078 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001079 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001080 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1081
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001082 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001083 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001084
1085 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001086
Tim Peters0bb44a42000-09-15 07:44:49 +00001087#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001088
1089#ifndef MAX_PATH
1090#define MAX_PATH CCHMAXPATH
1091#endif
1092 char *name, *pt;
1093 int len;
1094 PyObject *d, *v;
1095 char namebuf[MAX_PATH+5];
1096 HDIR hdir = 1;
1097 ULONG srchcnt = 1;
1098 FILEFINDBUF3 ep;
1099 APIRET rc;
1100
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001101 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001102 return NULL;
1103 if (len >= MAX_PATH) {
1104 PyErr_SetString(PyExc_ValueError, "path too long");
1105 return NULL;
1106 }
1107 strcpy(namebuf, name);
1108 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001109 if (*pt == ALTSEP)
1110 *pt = SEP;
1111 if (namebuf[len-1] != SEP)
1112 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001113 strcpy(namebuf + len, "*.*");
1114
1115 if ((d = PyList_New(0)) == NULL)
1116 return NULL;
1117
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001118 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1119 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001120 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001121 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1122 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1123 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001124
1125 if (rc != NO_ERROR) {
1126 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001127 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001128 }
1129
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001130 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001131 do {
1132 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001133 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001134 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001135
1136 strcpy(namebuf, ep.achName);
1137
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001138 /* Leave Case of Name Alone -- In Native Form */
1139 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001140
1141 v = PyString_FromString(namebuf);
1142 if (v == NULL) {
1143 Py_DECREF(d);
1144 d = NULL;
1145 break;
1146 }
1147 if (PyList_Append(d, v) != 0) {
1148 Py_DECREF(v);
1149 Py_DECREF(d);
1150 d = NULL;
1151 break;
1152 }
1153 Py_DECREF(v);
1154 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1155 }
1156
1157 return d;
1158#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001159
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001160 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001161 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001162 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001163 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001164 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001165 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001166 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001167 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001168 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001169 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001170 closedir(dirp);
1171 return NULL;
1172 }
1173 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001174 if (ep->d_name[0] == '.' &&
1175 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001176 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001177 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001178 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001179 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001180 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001181 d = NULL;
1182 break;
1183 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001184 if (PyList_Append(d, v) != 0) {
1185 Py_DECREF(v);
1186 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001187 d = NULL;
1188 break;
1189 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001190 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001191 }
1192 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001193
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001194 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001195
Tim Peters0bb44a42000-09-15 07:44:49 +00001196#endif /* which OS */
1197} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001198
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001199#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001200/* A helper function for abspath on win32 */
1201static PyObject *
1202posix__getfullpathname(PyObject *self, PyObject *args)
1203{
1204 /* assume encoded strings wont more than double no of chars */
1205 char inbuf[MAX_PATH*2];
1206 char *inbufp = inbuf;
1207 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1208 char outbuf[MAX_PATH*2];
1209 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001210 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1211 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001212 &insize))
1213 return NULL;
1214 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1215 outbuf, &temp))
1216 return win32_error("GetFullPathName", inbuf);
1217 return PyString_FromString(outbuf);
1218} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001219#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001220
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001221PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001222"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001223Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001224
Barry Warsaw53699e91996-12-10 23:23:01 +00001225static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001226posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001227{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001228 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001229 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001230 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001231 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001232 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001233 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001234 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001235#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001236 res = mkdir(path);
1237#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001238 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001239#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001240 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001241 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001242 return posix_error_with_allocated_filename(path);
1243 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001244 Py_INCREF(Py_None);
1245 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001246}
1247
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001248
Guido van Rossumb6775db1994-08-01 11:34:53 +00001249#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001250#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1251#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1252#include <sys/resource.h>
1253#endif
1254#endif
1255
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001256PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001257"nice(inc) -> new_priority\n\n\
1258Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001259
Barry Warsaw53699e91996-12-10 23:23:01 +00001260static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001261posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001262{
1263 int increment, value;
1264
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001265 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001266 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001267
1268 /* There are two flavours of 'nice': one that returns the new
1269 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001270 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1271 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001272
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001273 If we are of the nice family that returns the new priority, we
1274 need to clear errno before the call, and check if errno is filled
1275 before calling posix_error() on a returnvalue of -1, because the
1276 -1 may be the actual new priority! */
1277
1278 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001279 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001280#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001281 if (value == 0)
1282 value = getpriority(PRIO_PROCESS, 0);
1283#endif
1284 if (value == -1 && errno != 0)
1285 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001286 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001287 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001288}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001289#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001291
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001292PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001293"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001294Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001295
Barry Warsaw53699e91996-12-10 23:23:01 +00001296static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001297posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001298{
Mark Hammondef8b6542001-05-13 08:04:26 +00001299 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001300}
1301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001303PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001304"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001305Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001306
Barry Warsaw53699e91996-12-10 23:23:01 +00001307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001308posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001309{
Mark Hammondef8b6542001-05-13 08:04:26 +00001310 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001311}
1312
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001313
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001314PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001315"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001316Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001317
Barry Warsaw53699e91996-12-10 23:23:01 +00001318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001319posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001320{
Mark Hammondef8b6542001-05-13 08:04:26 +00001321 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001322}
1323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001324
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001325#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001326PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001327"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001328Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001329
Barry Warsaw53699e91996-12-10 23:23:01 +00001330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001331posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001332{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001333 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001334 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001335 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001336 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001337 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001338 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001339 Py_END_ALLOW_THREADS
1340 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001342#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001343
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001344
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001345PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001346"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001347Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001348
Barry Warsaw53699e91996-12-10 23:23:01 +00001349static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001350posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001351{
1352 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001353 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001354 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001355 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001356 if (i < 0)
1357 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001358 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001359}
1360
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001361
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001362PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001363"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001364Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001365
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001366PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001367"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001368Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001369
Barry Warsaw53699e91996-12-10 23:23:01 +00001370static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001371posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001372{
Mark Hammondef8b6542001-05-13 08:04:26 +00001373 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001374}
1375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001376
Guido van Rossumb6775db1994-08-01 11:34:53 +00001377#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001378PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001379"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001380Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001381
Barry Warsaw53699e91996-12-10 23:23:01 +00001382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001383posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001384{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001385 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001386 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001387 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001388 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001389 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001390 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001391 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001392 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001393 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001394 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001395 u.sysname,
1396 u.nodename,
1397 u.release,
1398 u.version,
1399 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001400}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001401#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001402
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001403static int
1404extract_time(PyObject *t, long* sec, long* usec)
1405{
1406 long intval;
1407 if (PyFloat_Check(t)) {
1408 double tval = PyFloat_AsDouble(t);
1409 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1410 if (!intobj)
1411 return -1;
1412 intval = PyInt_AsLong(intobj);
1413 Py_DECREF(intobj);
1414 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001415 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001416 if (*usec < 0)
1417 /* If rounding gave us a negative number,
1418 truncate. */
1419 *usec = 0;
1420 return 0;
1421 }
1422 intval = PyInt_AsLong(t);
1423 if (intval == -1 && PyErr_Occurred())
1424 return -1;
1425 *sec = intval;
1426 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001427 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001428}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001429
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001430PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001431"utime(path, (atime, utime))\n\
1432utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001433Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001434second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001435
Barry Warsaw53699e91996-12-10 23:23:01 +00001436static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001437posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001438{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001439 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001440 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001441 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001442 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001443
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001444#if defined(HAVE_UTIMES)
1445 struct timeval buf[2];
1446#define ATIME buf[0].tv_sec
1447#define MTIME buf[1].tv_sec
1448#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001449/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001450 struct utimbuf buf;
1451#define ATIME buf.actime
1452#define MTIME buf.modtime
1453#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001454#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001455 time_t buf[2];
1456#define ATIME buf[0]
1457#define MTIME buf[1]
1458#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001459#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001460
Barry Warsaw3cef8562000-05-01 16:17:24 +00001461 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001462 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001463 if (arg == Py_None) {
1464 /* optional time values not given */
1465 Py_BEGIN_ALLOW_THREADS
1466 res = utime(path, NULL);
1467 Py_END_ALLOW_THREADS
1468 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001469 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001470 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001471 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001472 return NULL;
1473 }
1474 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001475 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1476 &atime, &ausec) == -1)
1477 return NULL;
1478 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1479 &mtime, &musec) == -1)
1480 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001481 ATIME = atime;
1482 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001483#ifdef HAVE_UTIMES
1484 buf[0].tv_usec = ausec;
1485 buf[1].tv_usec = musec;
1486 Py_BEGIN_ALLOW_THREADS
1487 res = utimes(path, buf);
1488 Py_END_ALLOW_THREADS
1489#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001490 Py_BEGIN_ALLOW_THREADS
1491 res = utime(path, UTIME_ARG);
1492 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001493#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00001494 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001495 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001496 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001497 Py_INCREF(Py_None);
1498 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001499#undef UTIME_ARG
1500#undef ATIME
1501#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001502}
1503
Guido van Rossum85e3b011991-06-03 12:42:10 +00001504
Guido van Rossum3b066191991-06-04 19:40:25 +00001505/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001507PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001508"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001509Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001510
Barry Warsaw53699e91996-12-10 23:23:01 +00001511static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001512posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001513{
1514 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001515 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001516 return NULL;
1517 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001518 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001519}
1520
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001521
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001522#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001523PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001524"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001525Execute an executable path with arguments, replacing current process.\n\
1526\n\
1527 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001528 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001529
Barry Warsaw53699e91996-12-10 23:23:01 +00001530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001531posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001532{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001533 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001534 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001535 char **argvlist;
1536 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001537 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001538
Guido van Rossum89b33251993-10-22 14:26:06 +00001539 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001540 argv is a list or tuple of strings. */
1541
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001542 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001543 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001544 if (PyList_Check(argv)) {
1545 argc = PyList_Size(argv);
1546 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001547 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001548 else if (PyTuple_Check(argv)) {
1549 argc = PyTuple_Size(argv);
1550 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001551 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001552 else {
Fred Drake661ea262000-10-24 19:57:45 +00001553 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001554 return NULL;
1555 }
1556
1557 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001558 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001559 return NULL;
1560 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001561
Barry Warsaw53699e91996-12-10 23:23:01 +00001562 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001563 if (argvlist == NULL)
1564 return NULL;
1565 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001566 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1567 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001568 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001569 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001570 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001571
Guido van Rossum85e3b011991-06-03 12:42:10 +00001572 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001573 }
1574 argvlist[argc] = NULL;
1575
Guido van Rossumb6775db1994-08-01 11:34:53 +00001576#ifdef BAD_EXEC_PROTOTYPES
1577 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001578#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001579 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001580#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001581
Guido van Rossum85e3b011991-06-03 12:42:10 +00001582 /* If we get here it's definitely an error */
1583
Barry Warsaw53699e91996-12-10 23:23:01 +00001584 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001585 return posix_error();
1586}
1587
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001589PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001590"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001591Execute a path with arguments and environment, replacing current process.\n\
1592\n\
1593 path: path of executable file\n\
1594 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001595 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001596
Barry Warsaw53699e91996-12-10 23:23:01 +00001597static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001598posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001599{
1600 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001601 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001602 char **argvlist;
1603 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001604 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001605 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001606 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001607
1608 /* execve has three arguments: (path, argv, env), where
1609 argv is a list or tuple of strings and env is a dictionary
1610 like posix.environ. */
1611
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001612 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001613 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 if (PyList_Check(argv)) {
1615 argc = PyList_Size(argv);
1616 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001617 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001618 else if (PyTuple_Check(argv)) {
1619 argc = PyTuple_Size(argv);
1620 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001621 }
1622 else {
Fred Drake661ea262000-10-24 19:57:45 +00001623 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001624 return NULL;
1625 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001626 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001627 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001628 return NULL;
1629 }
1630
Guido van Rossum50422b42000-04-26 20:34:28 +00001631 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001632 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001633 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001634 return NULL;
1635 }
1636
Barry Warsaw53699e91996-12-10 23:23:01 +00001637 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001638 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001639 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001640 return NULL;
1641 }
1642 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001643 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001644 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001645 &argvlist[i]))
1646 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001647 goto fail_1;
1648 }
1649 }
1650 argvlist[argc] = NULL;
1651
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001652 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001653 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001654 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001655 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001656 goto fail_1;
1657 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001658 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001659 keys = PyMapping_Keys(env);
1660 vals = PyMapping_Values(env);
1661 if (!keys || !vals)
1662 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001663
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001664 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001665 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001666 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001667
1668 key = PyList_GetItem(keys, pos);
1669 val = PyList_GetItem(vals, pos);
1670 if (!key || !val)
1671 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001672
Fred Drake661ea262000-10-24 19:57:45 +00001673 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1674 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001675 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001676 goto fail_2;
1677 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001678
1679#if defined(PYOS_OS2)
1680 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1681 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1682#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001683 len = PyString_Size(key) + PyString_Size(val) + 2;
1684 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001685 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001686 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001687 goto fail_2;
1688 }
Tim Petersc8996f52001-12-03 20:41:00 +00001689 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001690 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001691#if defined(PYOS_OS2)
1692 }
1693#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001694 }
1695 envlist[envc] = 0;
1696
Guido van Rossumb6775db1994-08-01 11:34:53 +00001697
1698#ifdef BAD_EXEC_PROTOTYPES
1699 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001700#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001701 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001702#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001703
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001704 /* If we get here it's definitely an error */
1705
1706 (void) posix_error();
1707
1708 fail_2:
1709 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001710 PyMem_DEL(envlist[envc]);
1711 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001712 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001713 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001714 Py_XDECREF(vals);
1715 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001716 return NULL;
1717}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001718#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001719
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001720
Guido van Rossuma1065681999-01-25 23:20:23 +00001721#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001722PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001723"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001724Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001725\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001726 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001727 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001728 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001729
1730static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001731posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001732{
1733 char *path;
1734 PyObject *argv;
1735 char **argvlist;
1736 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001737 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001738 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001739
1740 /* spawnv has three arguments: (mode, path, argv), where
1741 argv is a list or tuple of strings. */
1742
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001743 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001744 return NULL;
1745 if (PyList_Check(argv)) {
1746 argc = PyList_Size(argv);
1747 getitem = PyList_GetItem;
1748 }
1749 else if (PyTuple_Check(argv)) {
1750 argc = PyTuple_Size(argv);
1751 getitem = PyTuple_GetItem;
1752 }
1753 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001754 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001755 return NULL;
1756 }
1757
1758 argvlist = PyMem_NEW(char *, argc+1);
1759 if (argvlist == NULL)
1760 return NULL;
1761 for (i = 0; i < argc; i++) {
1762 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1763 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001764 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001765 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001766 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001767 }
1768 }
1769 argvlist[argc] = NULL;
1770
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001771#if defined(PYOS_OS2) && defined(PYCC_GCC)
1772 Py_BEGIN_ALLOW_THREADS
1773 spawnval = spawnv(mode, path, argvlist);
1774 Py_END_ALLOW_THREADS
1775#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001776 if (mode == _OLD_P_OVERLAY)
1777 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001778
Tim Peters25059d32001-12-07 20:35:43 +00001779 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001780 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001781 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001782#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001783
Guido van Rossuma1065681999-01-25 23:20:23 +00001784 PyMem_DEL(argvlist);
1785
Fred Drake699f3522000-06-29 21:12:41 +00001786 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001787 return posix_error();
1788 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001789#if SIZEOF_LONG == SIZEOF_VOID_P
1790 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001791#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001792 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001793#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001794}
1795
1796
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001797PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001798"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001799Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001800\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001801 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001802 path: path of executable file\n\
1803 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001804 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001805
1806static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001807posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001808{
1809 char *path;
1810 PyObject *argv, *env;
1811 char **argvlist;
1812 char **envlist;
1813 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1814 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001815 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001816 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001817
1818 /* spawnve has four arguments: (mode, path, argv, env), where
1819 argv is a list or tuple of strings and env is a dictionary
1820 like posix.environ. */
1821
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001822 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001823 return NULL;
1824 if (PyList_Check(argv)) {
1825 argc = PyList_Size(argv);
1826 getitem = PyList_GetItem;
1827 }
1828 else if (PyTuple_Check(argv)) {
1829 argc = PyTuple_Size(argv);
1830 getitem = PyTuple_GetItem;
1831 }
1832 else {
Fred Drake661ea262000-10-24 19:57:45 +00001833 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001834 return NULL;
1835 }
1836 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001837 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001838 return NULL;
1839 }
1840
1841 argvlist = PyMem_NEW(char *, argc+1);
1842 if (argvlist == NULL) {
1843 PyErr_NoMemory();
1844 return NULL;
1845 }
1846 for (i = 0; i < argc; i++) {
1847 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001848 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001849 &argvlist[i]))
1850 {
1851 goto fail_1;
1852 }
1853 }
1854 argvlist[argc] = NULL;
1855
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001856 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001857 envlist = PyMem_NEW(char *, i + 1);
1858 if (envlist == NULL) {
1859 PyErr_NoMemory();
1860 goto fail_1;
1861 }
1862 envc = 0;
1863 keys = PyMapping_Keys(env);
1864 vals = PyMapping_Values(env);
1865 if (!keys || !vals)
1866 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001867
Guido van Rossuma1065681999-01-25 23:20:23 +00001868 for (pos = 0; pos < i; pos++) {
1869 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001870 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001871
1872 key = PyList_GetItem(keys, pos);
1873 val = PyList_GetItem(vals, pos);
1874 if (!key || !val)
1875 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001876
Fred Drake661ea262000-10-24 19:57:45 +00001877 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1878 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001879 {
1880 goto fail_2;
1881 }
Tim Petersc8996f52001-12-03 20:41:00 +00001882 len = PyString_Size(key) + PyString_Size(val) + 2;
1883 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001884 if (p == NULL) {
1885 PyErr_NoMemory();
1886 goto fail_2;
1887 }
Tim Petersc8996f52001-12-03 20:41:00 +00001888 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001889 envlist[envc++] = p;
1890 }
1891 envlist[envc] = 0;
1892
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001893#if defined(PYOS_OS2) && defined(PYCC_GCC)
1894 Py_BEGIN_ALLOW_THREADS
1895 spawnval = spawnve(mode, path, argvlist, envlist);
1896 Py_END_ALLOW_THREADS
1897#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001898 if (mode == _OLD_P_OVERLAY)
1899 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001900
1901 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001902 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001903 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001904#endif
Tim Peters25059d32001-12-07 20:35:43 +00001905
Fred Drake699f3522000-06-29 21:12:41 +00001906 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001907 (void) posix_error();
1908 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001909#if SIZEOF_LONG == SIZEOF_VOID_P
1910 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001911#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001912 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001913#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001914
1915 fail_2:
1916 while (--envc >= 0)
1917 PyMem_DEL(envlist[envc]);
1918 PyMem_DEL(envlist);
1919 fail_1:
1920 PyMem_DEL(argvlist);
1921 Py_XDECREF(vals);
1922 Py_XDECREF(keys);
1923 return res;
1924}
1925#endif /* HAVE_SPAWNV */
1926
1927
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001928#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001929PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001930"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001931Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1932\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001933Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001934
1935static PyObject *
1936posix_fork1(self, args)
1937 PyObject *self;
1938 PyObject *args;
1939{
1940 int pid;
1941 if (!PyArg_ParseTuple(args, ":fork1"))
1942 return NULL;
1943 pid = fork1();
1944 if (pid == -1)
1945 return posix_error();
1946 PyOS_AfterFork();
1947 return PyInt_FromLong((long)pid);
1948}
1949#endif
1950
1951
Guido van Rossumad0ee831995-03-01 10:34:45 +00001952#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001954"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001955Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001956Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001957
Barry Warsaw53699e91996-12-10 23:23:01 +00001958static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001959posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001960{
1961 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001962 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001963 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001964 pid = fork();
1965 if (pid == -1)
1966 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001967 if (pid == 0)
1968 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001969 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001970}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001971#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001972
Fred Drake8cef4cf2000-06-28 16:40:38 +00001973#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1974#ifdef HAVE_PTY_H
1975#include <pty.h>
1976#else
1977#ifdef HAVE_LIBUTIL_H
1978#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001979#endif /* HAVE_LIBUTIL_H */
1980#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001981#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001982
Thomas Wouters70c21a12000-07-14 14:28:33 +00001983#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001984PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001985"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001986Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001987
1988static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001989posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001990{
1991 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001992#ifndef HAVE_OPENPTY
1993 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001994#endif
1995
Fred Drake8cef4cf2000-06-28 16:40:38 +00001996 if (!PyArg_ParseTuple(args, ":openpty"))
1997 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001998
1999#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002000 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2001 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00002002#else
2003 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2004 if (slave_name == NULL)
2005 return posix_error();
2006
2007 slave_fd = open(slave_name, O_RDWR);
2008 if (slave_fd < 0)
2009 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002010#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002011
Fred Drake8cef4cf2000-06-28 16:40:38 +00002012 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002013
Fred Drake8cef4cf2000-06-28 16:40:38 +00002014}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002015#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002016
2017#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002018PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002019"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002020Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2021Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002022To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002023
2024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002025posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002026{
2027 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002028
Fred Drake8cef4cf2000-06-28 16:40:38 +00002029 if (!PyArg_ParseTuple(args, ":forkpty"))
2030 return NULL;
2031 pid = forkpty(&master_fd, NULL, NULL, NULL);
2032 if (pid == -1)
2033 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002034 if (pid == 0)
2035 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002036 return Py_BuildValue("(ii)", pid, master_fd);
2037}
2038#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002039
Guido van Rossumad0ee831995-03-01 10:34:45 +00002040#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002042"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002044
Barry Warsaw53699e91996-12-10 23:23:01 +00002045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002046posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002047{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002048 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002049 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002050 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002051}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002052#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002053
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002054
Guido van Rossumad0ee831995-03-01 10:34:45 +00002055#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002056PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002057"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002058Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059
Barry Warsaw53699e91996-12-10 23:23:01 +00002060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002061posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002062{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002063 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002064 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002065 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002066}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002067#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002069
Guido van Rossumad0ee831995-03-01 10:34:45 +00002070#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002072"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002074
Barry Warsaw53699e91996-12-10 23:23:01 +00002075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002076posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002077{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002078 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002079 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002080 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002081}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002082#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002084
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002085PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002086"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002087Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002088
Barry Warsaw53699e91996-12-10 23:23:01 +00002089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002090posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002091{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002092 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002093 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002094 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002095}
2096
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002097
Fred Drakec9680921999-12-13 16:37:25 +00002098#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002099PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002100"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002101Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002102
2103static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002104posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002105{
2106 PyObject *result = NULL;
2107
2108 if (PyArg_ParseTuple(args, ":getgroups")) {
2109#ifdef NGROUPS_MAX
2110#define MAX_GROUPS NGROUPS_MAX
2111#else
2112 /* defined to be 16 on Solaris7, so this should be a small number */
2113#define MAX_GROUPS 64
2114#endif
2115 gid_t grouplist[MAX_GROUPS];
2116 int n;
2117
2118 n = getgroups(MAX_GROUPS, grouplist);
2119 if (n < 0)
2120 posix_error();
2121 else {
2122 result = PyList_New(n);
2123 if (result != NULL) {
2124 PyObject *o;
2125 int i;
2126 for (i = 0; i < n; ++i) {
2127 o = PyInt_FromLong((long)grouplist[i]);
2128 if (o == NULL) {
2129 Py_DECREF(result);
2130 result = NULL;
2131 break;
2132 }
2133 PyList_SET_ITEM(result, i, o);
2134 }
2135 }
2136 }
2137 }
2138 return result;
2139}
2140#endif
2141
Martin v. Löwis606edc12002-06-13 21:09:11 +00002142#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002143PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002144"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002145Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002146
2147static PyObject *
2148posix_getpgid(PyObject *self, PyObject *args)
2149{
2150 int pid, pgid;
2151 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2152 return NULL;
2153 pgid = getpgid(pid);
2154 if (pgid < 0)
2155 return posix_error();
2156 return PyInt_FromLong((long)pgid);
2157}
2158#endif /* HAVE_GETPGID */
2159
2160
Guido van Rossumb6775db1994-08-01 11:34:53 +00002161#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002162PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002163"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002164Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002165
Barry Warsaw53699e91996-12-10 23:23:01 +00002166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002167posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002168{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002169 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002170 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002171#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002172 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002173#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002174 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002175#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002176}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002177#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002179
Guido van Rossumb6775db1994-08-01 11:34:53 +00002180#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002181PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002182"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002183Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002184
Barry Warsaw53699e91996-12-10 23:23:01 +00002185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002186posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002187{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002188 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002189 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002190#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002191 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002192#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002193 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002194#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002195 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002196 Py_INCREF(Py_None);
2197 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002198}
2199
Guido van Rossumb6775db1994-08-01 11:34:53 +00002200#endif /* HAVE_SETPGRP */
2201
Guido van Rossumad0ee831995-03-01 10:34:45 +00002202#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002203PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002204"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002205Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002206
Barry Warsaw53699e91996-12-10 23:23:01 +00002207static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002208posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002209{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002210 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002211 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002212 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002213}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002214#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002216
Fred Drake12c6e2d1999-12-14 21:25:03 +00002217#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002218PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002219"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002220Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002221
2222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002223posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002224{
2225 PyObject *result = NULL;
2226
2227 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002228 char *name;
2229 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002230
Fred Drakea30680b2000-12-06 21:24:28 +00002231 errno = 0;
2232 name = getlogin();
2233 if (name == NULL) {
2234 if (errno)
2235 posix_error();
2236 else
2237 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002238 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002239 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002240 else
2241 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002242 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002243 }
2244 return result;
2245}
2246#endif
2247
Guido van Rossumad0ee831995-03-01 10:34:45 +00002248#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002249PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002250"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002251Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002252
Barry Warsaw53699e91996-12-10 23:23:01 +00002253static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002254posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002255{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002256 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002257 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002258 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002259}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002260#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002261
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002262
Guido van Rossumad0ee831995-03-01 10:34:45 +00002263#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002264PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002265"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002266Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002267
Barry Warsaw53699e91996-12-10 23:23:01 +00002268static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002269posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002270{
2271 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002272 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002273 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002274#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002275 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2276 APIRET rc;
2277 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002278 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002279
2280 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2281 APIRET rc;
2282 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002283 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002284
2285 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002286 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002287#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002288 if (kill(pid, sig) == -1)
2289 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002290#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002291 Py_INCREF(Py_None);
2292 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002293}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002294#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002295
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002296#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002297PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002298"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002299Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002300
2301static PyObject *
2302posix_killpg(PyObject *self, PyObject *args)
2303{
2304 int pgid, sig;
2305 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2306 return NULL;
2307 if (killpg(pgid, sig) == -1)
2308 return posix_error();
2309 Py_INCREF(Py_None);
2310 return Py_None;
2311}
2312#endif
2313
Guido van Rossumc0125471996-06-28 18:55:32 +00002314#ifdef HAVE_PLOCK
2315
2316#ifdef HAVE_SYS_LOCK_H
2317#include <sys/lock.h>
2318#endif
2319
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002320PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002321"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002322Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002323
Barry Warsaw53699e91996-12-10 23:23:01 +00002324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002325posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002326{
2327 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002328 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002329 return NULL;
2330 if (plock(op) == -1)
2331 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002332 Py_INCREF(Py_None);
2333 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002334}
2335#endif
2336
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002337
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002338#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002339PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002340"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002341Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002342
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002343#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002344#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002345static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002346async_system(const char *command)
2347{
2348 char *p, errormsg[256], args[1024];
2349 RESULTCODES rcodes;
2350 APIRET rc;
2351 char *shell = getenv("COMSPEC");
2352 if (!shell)
2353 shell = "cmd";
2354
2355 strcpy(args, shell);
2356 p = &args[ strlen(args)+1 ];
2357 strcpy(p, "/c ");
2358 strcat(p, command);
2359 p += strlen(p) + 1;
2360 *p = '\0';
2361
2362 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002363 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002364 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002365 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002366 &rcodes, shell);
2367 return rc;
2368}
2369
Guido van Rossumd48f2521997-12-05 22:19:34 +00002370static FILE *
2371popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002372{
2373 HFILE rhan, whan;
2374 FILE *retfd = NULL;
2375 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2376
Guido van Rossumd48f2521997-12-05 22:19:34 +00002377 if (rc != NO_ERROR) {
2378 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002379 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002380 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002381
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002382 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2383 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002384
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002385 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2386 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002387
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002388 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2389 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002390
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002391 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002392 }
2393
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002394 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2395 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002396
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002397 if (rc == NO_ERROR)
2398 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2399
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002400 close(oldfd); /* And Close Saved STDOUT Handle */
2401 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002402
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002403 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2404 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002405
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002406 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2407 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002408
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002409 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2410 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002411
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002412 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002413 }
2414
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002415 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2416 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002417
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002418 if (rc == NO_ERROR)
2419 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2420
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002421 close(oldfd); /* And Close Saved STDIN Handle */
2422 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002423
Guido van Rossumd48f2521997-12-05 22:19:34 +00002424 } else {
2425 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002426 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002427 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002428}
2429
2430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002431posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002432{
2433 char *name;
2434 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002435 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002436 FILE *fp;
2437 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002438 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002439 return NULL;
2440 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002441 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002442 Py_END_ALLOW_THREADS
2443 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002444 return os2_error(err);
2445
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002446 f = PyFile_FromFile(fp, name, mode, fclose);
2447 if (f != NULL)
2448 PyFile_SetBufSize(f, bufsize);
2449 return f;
2450}
2451
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002452#elif defined(PYCC_GCC)
2453
2454/* standard posix version of popen() support */
2455static PyObject *
2456posix_popen(PyObject *self, PyObject *args)
2457{
2458 char *name;
2459 char *mode = "r";
2460 int bufsize = -1;
2461 FILE *fp;
2462 PyObject *f;
2463 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2464 return NULL;
2465 Py_BEGIN_ALLOW_THREADS
2466 fp = popen(name, mode);
2467 Py_END_ALLOW_THREADS
2468 if (fp == NULL)
2469 return posix_error();
2470 f = PyFile_FromFile(fp, name, mode, pclose);
2471 if (f != NULL)
2472 PyFile_SetBufSize(f, bufsize);
2473 return f;
2474}
2475
2476/* fork() under OS/2 has lots'o'warts
2477 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2478 * most of this code is a ripoff of the win32 code, but using the
2479 * capabilities of EMX's C library routines
2480 */
2481
2482/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2483#define POPEN_1 1
2484#define POPEN_2 2
2485#define POPEN_3 3
2486#define POPEN_4 4
2487
2488static PyObject *_PyPopen(char *, int, int, int);
2489static int _PyPclose(FILE *file);
2490
2491/*
2492 * Internal dictionary mapping popen* file pointers to process handles,
2493 * for use when retrieving the process exit code. See _PyPclose() below
2494 * for more information on this dictionary's use.
2495 */
2496static PyObject *_PyPopenProcs = NULL;
2497
2498/* os2emx version of popen2()
2499 *
2500 * The result of this function is a pipe (file) connected to the
2501 * process's stdin, and a pipe connected to the process's stdout.
2502 */
2503
2504static PyObject *
2505os2emx_popen2(PyObject *self, PyObject *args)
2506{
2507 PyObject *f;
2508 int tm=0;
2509
2510 char *cmdstring;
2511 char *mode = "t";
2512 int bufsize = -1;
2513 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2514 return NULL;
2515
2516 if (*mode == 't')
2517 tm = O_TEXT;
2518 else if (*mode != 'b') {
2519 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2520 return NULL;
2521 } else
2522 tm = O_BINARY;
2523
2524 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2525
2526 return f;
2527}
2528
2529/*
2530 * Variation on os2emx.popen2
2531 *
2532 * The result of this function is 3 pipes - the process's stdin,
2533 * stdout and stderr
2534 */
2535
2536static PyObject *
2537os2emx_popen3(PyObject *self, PyObject *args)
2538{
2539 PyObject *f;
2540 int tm = 0;
2541
2542 char *cmdstring;
2543 char *mode = "t";
2544 int bufsize = -1;
2545 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2546 return NULL;
2547
2548 if (*mode == 't')
2549 tm = O_TEXT;
2550 else if (*mode != 'b') {
2551 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2552 return NULL;
2553 } else
2554 tm = O_BINARY;
2555
2556 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2557
2558 return f;
2559}
2560
2561/*
2562 * Variation on os2emx.popen2
2563 *
2564 * The result of this function is 2 pipes - the processes stdin,
2565 * and stdout+stderr combined as a single pipe.
2566 */
2567
2568static PyObject *
2569os2emx_popen4(PyObject *self, PyObject *args)
2570{
2571 PyObject *f;
2572 int tm = 0;
2573
2574 char *cmdstring;
2575 char *mode = "t";
2576 int bufsize = -1;
2577 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2578 return NULL;
2579
2580 if (*mode == 't')
2581 tm = O_TEXT;
2582 else if (*mode != 'b') {
2583 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2584 return NULL;
2585 } else
2586 tm = O_BINARY;
2587
2588 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2589
2590 return f;
2591}
2592
2593/* a couple of structures for convenient handling of multiple
2594 * file handles and pipes
2595 */
2596struct file_ref
2597{
2598 int handle;
2599 int flags;
2600};
2601
2602struct pipe_ref
2603{
2604 int rd;
2605 int wr;
2606};
2607
2608/* The following code is derived from the win32 code */
2609
2610static PyObject *
2611_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2612{
2613 struct file_ref stdio[3];
2614 struct pipe_ref p_fd[3];
2615 FILE *p_s[3];
2616 int file_count, i, pipe_err, pipe_pid;
2617 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2618 PyObject *f, *p_f[3];
2619
2620 /* file modes for subsequent fdopen's on pipe handles */
2621 if (mode == O_TEXT)
2622 {
2623 rd_mode = "rt";
2624 wr_mode = "wt";
2625 }
2626 else
2627 {
2628 rd_mode = "rb";
2629 wr_mode = "wb";
2630 }
2631
2632 /* prepare shell references */
2633 if ((shell = getenv("EMXSHELL")) == NULL)
2634 if ((shell = getenv("COMSPEC")) == NULL)
2635 {
2636 errno = ENOENT;
2637 return posix_error();
2638 }
2639
2640 sh_name = _getname(shell);
2641 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2642 opt = "/c";
2643 else
2644 opt = "-c";
2645
2646 /* save current stdio fds + their flags, and set not inheritable */
2647 i = pipe_err = 0;
2648 while (pipe_err >= 0 && i < 3)
2649 {
2650 pipe_err = stdio[i].handle = dup(i);
2651 stdio[i].flags = fcntl(i, F_GETFD, 0);
2652 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2653 i++;
2654 }
2655 if (pipe_err < 0)
2656 {
2657 /* didn't get them all saved - clean up and bail out */
2658 int saved_err = errno;
2659 while (i-- > 0)
2660 {
2661 close(stdio[i].handle);
2662 }
2663 errno = saved_err;
2664 return posix_error();
2665 }
2666
2667 /* create pipe ends */
2668 file_count = 2;
2669 if (n == POPEN_3)
2670 file_count = 3;
2671 i = pipe_err = 0;
2672 while ((pipe_err == 0) && (i < file_count))
2673 pipe_err = pipe((int *)&p_fd[i++]);
2674 if (pipe_err < 0)
2675 {
2676 /* didn't get them all made - clean up and bail out */
2677 while (i-- > 0)
2678 {
2679 close(p_fd[i].wr);
2680 close(p_fd[i].rd);
2681 }
2682 errno = EPIPE;
2683 return posix_error();
2684 }
2685
2686 /* change the actual standard IO streams over temporarily,
2687 * making the retained pipe ends non-inheritable
2688 */
2689 pipe_err = 0;
2690
2691 /* - stdin */
2692 if (dup2(p_fd[0].rd, 0) == 0)
2693 {
2694 close(p_fd[0].rd);
2695 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2696 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2697 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2698 {
2699 close(p_fd[0].wr);
2700 pipe_err = -1;
2701 }
2702 }
2703 else
2704 {
2705 pipe_err = -1;
2706 }
2707
2708 /* - stdout */
2709 if (pipe_err == 0)
2710 {
2711 if (dup2(p_fd[1].wr, 1) == 1)
2712 {
2713 close(p_fd[1].wr);
2714 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2715 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2716 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2717 {
2718 close(p_fd[1].rd);
2719 pipe_err = -1;
2720 }
2721 }
2722 else
2723 {
2724 pipe_err = -1;
2725 }
2726 }
2727
2728 /* - stderr, as required */
2729 if (pipe_err == 0)
2730 switch (n)
2731 {
2732 case POPEN_3:
2733 {
2734 if (dup2(p_fd[2].wr, 2) == 2)
2735 {
2736 close(p_fd[2].wr);
2737 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2738 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2739 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2740 {
2741 close(p_fd[2].rd);
2742 pipe_err = -1;
2743 }
2744 }
2745 else
2746 {
2747 pipe_err = -1;
2748 }
2749 break;
2750 }
2751
2752 case POPEN_4:
2753 {
2754 if (dup2(1, 2) != 2)
2755 {
2756 pipe_err = -1;
2757 }
2758 break;
2759 }
2760 }
2761
2762 /* spawn the child process */
2763 if (pipe_err == 0)
2764 {
2765 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2766 if (pipe_pid == -1)
2767 {
2768 pipe_err = -1;
2769 }
2770 else
2771 {
2772 /* save the PID into the FILE structure
2773 * NOTE: this implementation doesn't actually
2774 * take advantage of this, but do it for
2775 * completeness - AIM Apr01
2776 */
2777 for (i = 0; i < file_count; i++)
2778 p_s[i]->_pid = pipe_pid;
2779 }
2780 }
2781
2782 /* reset standard IO to normal */
2783 for (i = 0; i < 3; i++)
2784 {
2785 dup2(stdio[i].handle, i);
2786 fcntl(i, F_SETFD, stdio[i].flags);
2787 close(stdio[i].handle);
2788 }
2789
2790 /* if any remnant problems, clean up and bail out */
2791 if (pipe_err < 0)
2792 {
2793 for (i = 0; i < 3; i++)
2794 {
2795 close(p_fd[i].rd);
2796 close(p_fd[i].wr);
2797 }
2798 errno = EPIPE;
2799 return posix_error_with_filename(cmdstring);
2800 }
2801
2802 /* build tuple of file objects to return */
2803 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2804 PyFile_SetBufSize(p_f[0], bufsize);
2805 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2806 PyFile_SetBufSize(p_f[1], bufsize);
2807 if (n == POPEN_3)
2808 {
2809 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2810 PyFile_SetBufSize(p_f[0], bufsize);
2811 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2812 }
2813 else
2814 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2815
2816 /*
2817 * Insert the files we've created into the process dictionary
2818 * all referencing the list with the process handle and the
2819 * initial number of files (see description below in _PyPclose).
2820 * Since if _PyPclose later tried to wait on a process when all
2821 * handles weren't closed, it could create a deadlock with the
2822 * child, we spend some energy here to try to ensure that we
2823 * either insert all file handles into the dictionary or none
2824 * at all. It's a little clumsy with the various popen modes
2825 * and variable number of files involved.
2826 */
2827 if (!_PyPopenProcs)
2828 {
2829 _PyPopenProcs = PyDict_New();
2830 }
2831
2832 if (_PyPopenProcs)
2833 {
2834 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2835 int ins_rc[3];
2836
2837 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2838 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2839
2840 procObj = PyList_New(2);
2841 pidObj = PyInt_FromLong((long) pipe_pid);
2842 intObj = PyInt_FromLong((long) file_count);
2843
2844 if (procObj && pidObj && intObj)
2845 {
2846 PyList_SetItem(procObj, 0, pidObj);
2847 PyList_SetItem(procObj, 1, intObj);
2848
2849 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2850 if (fileObj[0])
2851 {
2852 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2853 fileObj[0],
2854 procObj);
2855 }
2856 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2857 if (fileObj[1])
2858 {
2859 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2860 fileObj[1],
2861 procObj);
2862 }
2863 if (file_count >= 3)
2864 {
2865 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2866 if (fileObj[2])
2867 {
2868 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2869 fileObj[2],
2870 procObj);
2871 }
2872 }
2873
2874 if (ins_rc[0] < 0 || !fileObj[0] ||
2875 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2876 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2877 {
2878 /* Something failed - remove any dictionary
2879 * entries that did make it.
2880 */
2881 if (!ins_rc[0] && fileObj[0])
2882 {
2883 PyDict_DelItem(_PyPopenProcs,
2884 fileObj[0]);
2885 }
2886 if (!ins_rc[1] && fileObj[1])
2887 {
2888 PyDict_DelItem(_PyPopenProcs,
2889 fileObj[1]);
2890 }
2891 if (!ins_rc[2] && fileObj[2])
2892 {
2893 PyDict_DelItem(_PyPopenProcs,
2894 fileObj[2]);
2895 }
2896 }
2897 }
2898
2899 /*
2900 * Clean up our localized references for the dictionary keys
2901 * and value since PyDict_SetItem will Py_INCREF any copies
2902 * that got placed in the dictionary.
2903 */
2904 Py_XDECREF(procObj);
2905 Py_XDECREF(fileObj[0]);
2906 Py_XDECREF(fileObj[1]);
2907 Py_XDECREF(fileObj[2]);
2908 }
2909
2910 /* Child is launched. */
2911 return f;
2912}
2913
2914/*
2915 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2916 * exit code for the child process and return as a result of the close.
2917 *
2918 * This function uses the _PyPopenProcs dictionary in order to map the
2919 * input file pointer to information about the process that was
2920 * originally created by the popen* call that created the file pointer.
2921 * The dictionary uses the file pointer as a key (with one entry
2922 * inserted for each file returned by the original popen* call) and a
2923 * single list object as the value for all files from a single call.
2924 * The list object contains the Win32 process handle at [0], and a file
2925 * count at [1], which is initialized to the total number of file
2926 * handles using that list.
2927 *
2928 * This function closes whichever handle it is passed, and decrements
2929 * the file count in the dictionary for the process handle pointed to
2930 * by this file. On the last close (when the file count reaches zero),
2931 * this function will wait for the child process and then return its
2932 * exit code as the result of the close() operation. This permits the
2933 * files to be closed in any order - it is always the close() of the
2934 * final handle that will return the exit code.
2935 */
2936
2937 /* RED_FLAG 31-Aug-2000 Tim
2938 * This is always called (today!) between a pair of
2939 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2940 * macros. So the thread running this has no valid thread state, as
2941 * far as Python is concerned. However, this calls some Python API
2942 * functions that cannot be called safely without a valid thread
2943 * state, in particular PyDict_GetItem.
2944 * As a temporary hack (although it may last for years ...), we
2945 * *rely* on not having a valid thread state in this function, in
2946 * order to create our own "from scratch".
2947 * This will deadlock if _PyPclose is ever called by a thread
2948 * holding the global lock.
2949 * (The OS/2 EMX thread support appears to cover the case where the
2950 * lock is already held - AIM Apr01)
2951 */
2952
2953static int _PyPclose(FILE *file)
2954{
2955 int result;
2956 int exit_code;
2957 int pipe_pid;
2958 PyObject *procObj, *pidObj, *intObj, *fileObj;
2959 int file_count;
2960#ifdef WITH_THREAD
2961 PyInterpreterState* pInterpreterState;
2962 PyThreadState* pThreadState;
2963#endif
2964
2965 /* Close the file handle first, to ensure it can't block the
2966 * child from exiting if it's the last handle.
2967 */
2968 result = fclose(file);
2969
2970#ifdef WITH_THREAD
2971 /* Bootstrap a valid thread state into existence. */
2972 pInterpreterState = PyInterpreterState_New();
2973 if (!pInterpreterState) {
2974 /* Well, we're hosed now! We don't have a thread
2975 * state, so can't call a nice error routine, or raise
2976 * an exception. Just die.
2977 */
2978 Py_FatalError("unable to allocate interpreter state "
2979 "when closing popen object.");
2980 return -1; /* unreachable */
2981 }
2982 pThreadState = PyThreadState_New(pInterpreterState);
2983 if (!pThreadState) {
2984 Py_FatalError("unable to allocate thread state "
2985 "when closing popen object.");
2986 return -1; /* unreachable */
2987 }
2988 /* Grab the global lock. Note that this will deadlock if the
2989 * current thread already has the lock! (see RED_FLAG comments
2990 * before this function)
2991 */
2992 PyEval_RestoreThread(pThreadState);
2993#endif
2994
2995 if (_PyPopenProcs)
2996 {
2997 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2998 (procObj = PyDict_GetItem(_PyPopenProcs,
2999 fileObj)) != NULL &&
3000 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3001 (intObj = PyList_GetItem(procObj,1)) != NULL)
3002 {
3003 pipe_pid = (int) PyInt_AsLong(pidObj);
3004 file_count = (int) PyInt_AsLong(intObj);
3005
3006 if (file_count > 1)
3007 {
3008 /* Still other files referencing process */
3009 file_count--;
3010 PyList_SetItem(procObj,1,
3011 PyInt_FromLong((long) file_count));
3012 }
3013 else
3014 {
3015 /* Last file for this process */
3016 if (result != EOF &&
3017 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3018 {
3019 /* extract exit status */
3020 if (WIFEXITED(exit_code))
3021 {
3022 result = WEXITSTATUS(exit_code);
3023 }
3024 else
3025 {
3026 errno = EPIPE;
3027 result = -1;
3028 }
3029 }
3030 else
3031 {
3032 /* Indicate failure - this will cause the file object
3033 * to raise an I/O error and translate the last
3034 * error code from errno. We do have a problem with
3035 * last errors that overlap the normal errno table,
3036 * but that's a consistent problem with the file object.
3037 */
3038 result = -1;
3039 }
3040 }
3041
3042 /* Remove this file pointer from dictionary */
3043 PyDict_DelItem(_PyPopenProcs, fileObj);
3044
3045 if (PyDict_Size(_PyPopenProcs) == 0)
3046 {
3047 Py_DECREF(_PyPopenProcs);
3048 _PyPopenProcs = NULL;
3049 }
3050
3051 } /* if object retrieval ok */
3052
3053 Py_XDECREF(fileObj);
3054 } /* if _PyPopenProcs */
3055
3056#ifdef WITH_THREAD
3057 /* Tear down the thread & interpreter states.
3058 * Note that interpreter state clear & delete functions automatically
3059 * call the thread clear & delete functions, and indeed insist on
3060 * doing that themselves. The lock must be held during the clear, but
3061 * need not be held during the delete.
3062 */
3063 PyInterpreterState_Clear(pInterpreterState);
3064 PyEval_ReleaseThread(pThreadState);
3065 PyInterpreterState_Delete(pInterpreterState);
3066#endif
3067
3068 return result;
3069}
3070
3071#endif /* PYCC_??? */
3072
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003073#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003074
3075/*
3076 * Portable 'popen' replacement for Win32.
3077 *
3078 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3079 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003080 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003081 */
3082
3083#include <malloc.h>
3084#include <io.h>
3085#include <fcntl.h>
3086
3087/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3088#define POPEN_1 1
3089#define POPEN_2 2
3090#define POPEN_3 3
3091#define POPEN_4 4
3092
3093static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003094static int _PyPclose(FILE *file);
3095
3096/*
3097 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003098 * for use when retrieving the process exit code. See _PyPclose() below
3099 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003100 */
3101static PyObject *_PyPopenProcs = NULL;
3102
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003103
3104/* popen that works from a GUI.
3105 *
3106 * The result of this function is a pipe (file) connected to the
3107 * processes stdin or stdout, depending on the requested mode.
3108 */
3109
3110static PyObject *
3111posix_popen(PyObject *self, PyObject *args)
3112{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003113 PyObject *f, *s;
3114 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003115
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003116 char *cmdstring;
3117 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003118 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003119 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003120 return NULL;
3121
3122 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003123
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003124 if (*mode == 'r')
3125 tm = _O_RDONLY;
3126 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003127 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003128 return NULL;
3129 } else
3130 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003131
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003132 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003133 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003134 return NULL;
3135 }
3136
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003137 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003138 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003139 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003140 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003141 else
3142 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3143
3144 return f;
3145}
3146
3147/* Variation on win32pipe.popen
3148 *
3149 * The result of this function is a pipe (file) connected to the
3150 * process's stdin, and a pipe connected to the process's stdout.
3151 */
3152
3153static PyObject *
3154win32_popen2(PyObject *self, PyObject *args)
3155{
3156 PyObject *f;
3157 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003158
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003159 char *cmdstring;
3160 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003161 int bufsize = -1;
3162 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003163 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003164
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003165 if (*mode == 't')
3166 tm = _O_TEXT;
3167 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003168 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003169 return NULL;
3170 } else
3171 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003172
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003173 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003174 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003175 return NULL;
3176 }
3177
3178 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003179
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003180 return f;
3181}
3182
3183/*
3184 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003185 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003186 * The result of this function is 3 pipes - the process's stdin,
3187 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003188 */
3189
3190static PyObject *
3191win32_popen3(PyObject *self, PyObject *args)
3192{
3193 PyObject *f;
3194 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003195
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003196 char *cmdstring;
3197 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003198 int bufsize = -1;
3199 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003200 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003201
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003202 if (*mode == 't')
3203 tm = _O_TEXT;
3204 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003205 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003206 return NULL;
3207 } else
3208 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003209
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003210 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003211 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003212 return NULL;
3213 }
3214
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003215 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003216
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003217 return f;
3218}
3219
3220/*
3221 * Variation on win32pipe.popen
3222 *
Tim Peters5aa91602002-01-30 05:46:57 +00003223 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003224 * and stdout+stderr combined as a single pipe.
3225 */
3226
3227static PyObject *
3228win32_popen4(PyObject *self, PyObject *args)
3229{
3230 PyObject *f;
3231 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003232
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003233 char *cmdstring;
3234 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003235 int bufsize = -1;
3236 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003237 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003238
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003239 if (*mode == 't')
3240 tm = _O_TEXT;
3241 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003242 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003243 return NULL;
3244 } else
3245 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003246
3247 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003248 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003249 return NULL;
3250 }
3251
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003252 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003253
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003254 return f;
3255}
3256
Mark Hammond08501372001-01-31 07:30:29 +00003257static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003258_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003259 HANDLE hStdin,
3260 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003261 HANDLE hStderr,
3262 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003263{
3264 PROCESS_INFORMATION piProcInfo;
3265 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003266 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003267 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003268 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003269 int i;
3270 int x;
3271
3272 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003273 char *comshell;
3274
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003275 s1 = (char *)_alloca(i);
3276 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3277 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003278
3279 /* Explicitly check if we are using COMMAND.COM. If we are
3280 * then use the w9xpopen hack.
3281 */
3282 comshell = s1 + x;
3283 while (comshell >= s1 && *comshell != '\\')
3284 --comshell;
3285 ++comshell;
3286
3287 if (GetVersion() < 0x80000000 &&
3288 _stricmp(comshell, "command.com") != 0) {
3289 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003290 x = i + strlen(s3) + strlen(cmdstring) + 1;
3291 s2 = (char *)_alloca(x);
3292 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003293 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003294 }
3295 else {
3296 /*
Tim Peters402d5982001-08-27 06:37:48 +00003297 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3298 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003299 */
Mark Hammond08501372001-01-31 07:30:29 +00003300 char modulepath[_MAX_PATH];
3301 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003302 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3303 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003304 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003305 x = i+1;
3306 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003307 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003308 strncat(modulepath,
3309 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003310 (sizeof(modulepath)/sizeof(modulepath[0]))
3311 -strlen(modulepath));
3312 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003313 /* Eeek - file-not-found - possibly an embedding
3314 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003315 */
Tim Peters5aa91602002-01-30 05:46:57 +00003316 strncpy(modulepath,
3317 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003318 sizeof(modulepath)/sizeof(modulepath[0]));
3319 if (modulepath[strlen(modulepath)-1] != '\\')
3320 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003321 strncat(modulepath,
3322 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003323 (sizeof(modulepath)/sizeof(modulepath[0]))
3324 -strlen(modulepath));
3325 /* No where else to look - raise an easily identifiable
3326 error, rather than leaving Windows to report
3327 "file not found" - as the user is probably blissfully
3328 unaware this shim EXE is used, and it will confuse them.
3329 (well, it confused me for a while ;-)
3330 */
3331 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003332 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003333 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003334 "for popen to work with your shell "
3335 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003336 szConsoleSpawn);
3337 return FALSE;
3338 }
3339 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003340 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003341 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003342 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003343
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003344 s2 = (char *)_alloca(x);
3345 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003346 /* To maintain correct argument passing semantics,
3347 we pass the command-line as it stands, and allow
3348 quoting to be applied. w9xpopen.exe will then
3349 use its argv vector, and re-quote the necessary
3350 args for the ultimate child process.
3351 */
Tim Peters75cdad52001-11-28 22:07:30 +00003352 PyOS_snprintf(
3353 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003354 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003355 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003356 s1,
3357 s3,
3358 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003359 /* Not passing CREATE_NEW_CONSOLE has been known to
3360 cause random failures on win9x. Specifically a
3361 dialog:
3362 "Your program accessed mem currently in use at xxx"
3363 and a hopeful warning about the stability of your
3364 system.
3365 Cost is Ctrl+C wont kill children, but anyone
3366 who cares can have a go!
3367 */
3368 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003369 }
3370 }
3371
3372 /* Could be an else here to try cmd.exe / command.com in the path
3373 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003374 else {
Tim Peters402d5982001-08-27 06:37:48 +00003375 PyErr_SetString(PyExc_RuntimeError,
3376 "Cannot locate a COMSPEC environment variable to "
3377 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003378 return FALSE;
3379 }
Tim Peters5aa91602002-01-30 05:46:57 +00003380
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003381 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3382 siStartInfo.cb = sizeof(STARTUPINFO);
3383 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3384 siStartInfo.hStdInput = hStdin;
3385 siStartInfo.hStdOutput = hStdout;
3386 siStartInfo.hStdError = hStderr;
3387 siStartInfo.wShowWindow = SW_HIDE;
3388
3389 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003390 s2,
3391 NULL,
3392 NULL,
3393 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003394 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003395 NULL,
3396 NULL,
3397 &siStartInfo,
3398 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003399 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003400 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003401
Mark Hammondb37a3732000-08-14 04:47:33 +00003402 /* Return process handle */
3403 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003404 return TRUE;
3405 }
Tim Peters402d5982001-08-27 06:37:48 +00003406 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003407 return FALSE;
3408}
3409
3410/* The following code is based off of KB: Q190351 */
3411
3412static PyObject *
3413_PyPopen(char *cmdstring, int mode, int n)
3414{
3415 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3416 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003417 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003418
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003419 SECURITY_ATTRIBUTES saAttr;
3420 BOOL fSuccess;
3421 int fd1, fd2, fd3;
3422 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003423 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003424 PyObject *f;
3425
3426 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3427 saAttr.bInheritHandle = TRUE;
3428 saAttr.lpSecurityDescriptor = NULL;
3429
3430 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3431 return win32_error("CreatePipe", NULL);
3432
3433 /* Create new output read handle and the input write handle. Set
3434 * the inheritance properties to FALSE. Otherwise, the child inherits
3435 * the these handles; resulting in non-closeable handles to the pipes
3436 * being created. */
3437 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003438 GetCurrentProcess(), &hChildStdinWrDup, 0,
3439 FALSE,
3440 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003441 if (!fSuccess)
3442 return win32_error("DuplicateHandle", NULL);
3443
3444 /* Close the inheritable version of ChildStdin
3445 that we're using. */
3446 CloseHandle(hChildStdinWr);
3447
3448 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3449 return win32_error("CreatePipe", NULL);
3450
3451 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003452 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3453 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003454 if (!fSuccess)
3455 return win32_error("DuplicateHandle", NULL);
3456
3457 /* Close the inheritable version of ChildStdout
3458 that we're using. */
3459 CloseHandle(hChildStdoutRd);
3460
3461 if (n != POPEN_4) {
3462 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3463 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003464 fSuccess = DuplicateHandle(GetCurrentProcess(),
3465 hChildStderrRd,
3466 GetCurrentProcess(),
3467 &hChildStderrRdDup, 0,
3468 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003469 if (!fSuccess)
3470 return win32_error("DuplicateHandle", NULL);
3471 /* Close the inheritable version of ChildStdErr that we're using. */
3472 CloseHandle(hChildStderrRd);
3473 }
Tim Peters5aa91602002-01-30 05:46:57 +00003474
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003475 switch (n) {
3476 case POPEN_1:
3477 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3478 case _O_WRONLY | _O_TEXT:
3479 /* Case for writing to child Stdin in text mode. */
3480 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3481 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003482 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003483 PyFile_SetBufSize(f, 0);
3484 /* We don't care about these pipes anymore, so close them. */
3485 CloseHandle(hChildStdoutRdDup);
3486 CloseHandle(hChildStderrRdDup);
3487 break;
3488
3489 case _O_RDONLY | _O_TEXT:
3490 /* Case for reading from child Stdout in text mode. */
3491 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3492 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003493 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003494 PyFile_SetBufSize(f, 0);
3495 /* We don't care about these pipes anymore, so close them. */
3496 CloseHandle(hChildStdinWrDup);
3497 CloseHandle(hChildStderrRdDup);
3498 break;
3499
3500 case _O_RDONLY | _O_BINARY:
3501 /* Case for readinig from child Stdout in binary mode. */
3502 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3503 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003504 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003505 PyFile_SetBufSize(f, 0);
3506 /* We don't care about these pipes anymore, so close them. */
3507 CloseHandle(hChildStdinWrDup);
3508 CloseHandle(hChildStderrRdDup);
3509 break;
3510
3511 case _O_WRONLY | _O_BINARY:
3512 /* Case for writing to child Stdin in binary mode. */
3513 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3514 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003515 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003516 PyFile_SetBufSize(f, 0);
3517 /* We don't care about these pipes anymore, so close them. */
3518 CloseHandle(hChildStdoutRdDup);
3519 CloseHandle(hChildStderrRdDup);
3520 break;
3521 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003522 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003523 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003524
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003525 case POPEN_2:
3526 case POPEN_4:
3527 {
3528 char *m1, *m2;
3529 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003530
Tim Peters7dca21e2002-08-19 00:42:29 +00003531 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003532 m1 = "r";
3533 m2 = "w";
3534 } else {
3535 m1 = "rb";
3536 m2 = "wb";
3537 }
3538
3539 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3540 f1 = _fdopen(fd1, m2);
3541 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3542 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003543 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003544 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003545 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003546 PyFile_SetBufSize(p2, 0);
3547
3548 if (n != 4)
3549 CloseHandle(hChildStderrRdDup);
3550
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003551 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003552 Py_XDECREF(p1);
3553 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003554 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003555 break;
3556 }
Tim Peters5aa91602002-01-30 05:46:57 +00003557
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003558 case POPEN_3:
3559 {
3560 char *m1, *m2;
3561 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003562
Tim Peters7dca21e2002-08-19 00:42:29 +00003563 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003564 m1 = "r";
3565 m2 = "w";
3566 } else {
3567 m1 = "rb";
3568 m2 = "wb";
3569 }
3570
3571 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3572 f1 = _fdopen(fd1, m2);
3573 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3574 f2 = _fdopen(fd2, m1);
3575 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3576 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003577 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003578 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3579 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003580 PyFile_SetBufSize(p1, 0);
3581 PyFile_SetBufSize(p2, 0);
3582 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003583 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003584 Py_XDECREF(p1);
3585 Py_XDECREF(p2);
3586 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003587 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003588 break;
3589 }
3590 }
3591
3592 if (n == POPEN_4) {
3593 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003594 hChildStdinRd,
3595 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003596 hChildStdoutWr,
3597 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003598 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003599 }
3600 else {
3601 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003602 hChildStdinRd,
3603 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003604 hChildStderrWr,
3605 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003606 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003607 }
3608
Mark Hammondb37a3732000-08-14 04:47:33 +00003609 /*
3610 * Insert the files we've created into the process dictionary
3611 * all referencing the list with the process handle and the
3612 * initial number of files (see description below in _PyPclose).
3613 * Since if _PyPclose later tried to wait on a process when all
3614 * handles weren't closed, it could create a deadlock with the
3615 * child, we spend some energy here to try to ensure that we
3616 * either insert all file handles into the dictionary or none
3617 * at all. It's a little clumsy with the various popen modes
3618 * and variable number of files involved.
3619 */
3620 if (!_PyPopenProcs) {
3621 _PyPopenProcs = PyDict_New();
3622 }
3623
3624 if (_PyPopenProcs) {
3625 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3626 int ins_rc[3];
3627
3628 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3629 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3630
3631 procObj = PyList_New(2);
3632 hProcessObj = PyLong_FromVoidPtr(hProcess);
3633 intObj = PyInt_FromLong(file_count);
3634
3635 if (procObj && hProcessObj && intObj) {
3636 PyList_SetItem(procObj,0,hProcessObj);
3637 PyList_SetItem(procObj,1,intObj);
3638
3639 fileObj[0] = PyLong_FromVoidPtr(f1);
3640 if (fileObj[0]) {
3641 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3642 fileObj[0],
3643 procObj);
3644 }
3645 if (file_count >= 2) {
3646 fileObj[1] = PyLong_FromVoidPtr(f2);
3647 if (fileObj[1]) {
3648 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3649 fileObj[1],
3650 procObj);
3651 }
3652 }
3653 if (file_count >= 3) {
3654 fileObj[2] = PyLong_FromVoidPtr(f3);
3655 if (fileObj[2]) {
3656 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3657 fileObj[2],
3658 procObj);
3659 }
3660 }
3661
3662 if (ins_rc[0] < 0 || !fileObj[0] ||
3663 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3664 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3665 /* Something failed - remove any dictionary
3666 * entries that did make it.
3667 */
3668 if (!ins_rc[0] && fileObj[0]) {
3669 PyDict_DelItem(_PyPopenProcs,
3670 fileObj[0]);
3671 }
3672 if (!ins_rc[1] && fileObj[1]) {
3673 PyDict_DelItem(_PyPopenProcs,
3674 fileObj[1]);
3675 }
3676 if (!ins_rc[2] && fileObj[2]) {
3677 PyDict_DelItem(_PyPopenProcs,
3678 fileObj[2]);
3679 }
3680 }
3681 }
Tim Peters5aa91602002-01-30 05:46:57 +00003682
Mark Hammondb37a3732000-08-14 04:47:33 +00003683 /*
3684 * Clean up our localized references for the dictionary keys
3685 * and value since PyDict_SetItem will Py_INCREF any copies
3686 * that got placed in the dictionary.
3687 */
3688 Py_XDECREF(procObj);
3689 Py_XDECREF(fileObj[0]);
3690 Py_XDECREF(fileObj[1]);
3691 Py_XDECREF(fileObj[2]);
3692 }
3693
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003694 /* Child is launched. Close the parents copy of those pipe
3695 * handles that only the child should have open. You need to
3696 * make sure that no handles to the write end of the output pipe
3697 * are maintained in this process or else the pipe will not close
3698 * when the child process exits and the ReadFile will hang. */
3699
3700 if (!CloseHandle(hChildStdinRd))
3701 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003702
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003703 if (!CloseHandle(hChildStdoutWr))
3704 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003705
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003706 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3707 return win32_error("CloseHandle", NULL);
3708
3709 return f;
3710}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003711
3712/*
3713 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3714 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003715 *
3716 * This function uses the _PyPopenProcs dictionary in order to map the
3717 * input file pointer to information about the process that was
3718 * originally created by the popen* call that created the file pointer.
3719 * The dictionary uses the file pointer as a key (with one entry
3720 * inserted for each file returned by the original popen* call) and a
3721 * single list object as the value for all files from a single call.
3722 * The list object contains the Win32 process handle at [0], and a file
3723 * count at [1], which is initialized to the total number of file
3724 * handles using that list.
3725 *
3726 * This function closes whichever handle it is passed, and decrements
3727 * the file count in the dictionary for the process handle pointed to
3728 * by this file. On the last close (when the file count reaches zero),
3729 * this function will wait for the child process and then return its
3730 * exit code as the result of the close() operation. This permits the
3731 * files to be closed in any order - it is always the close() of the
3732 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003733 */
Tim Peters736aa322000-09-01 06:51:24 +00003734
3735 /* RED_FLAG 31-Aug-2000 Tim
3736 * This is always called (today!) between a pair of
3737 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3738 * macros. So the thread running this has no valid thread state, as
3739 * far as Python is concerned. However, this calls some Python API
3740 * functions that cannot be called safely without a valid thread
3741 * state, in particular PyDict_GetItem.
3742 * As a temporary hack (although it may last for years ...), we
3743 * *rely* on not having a valid thread state in this function, in
3744 * order to create our own "from scratch".
3745 * This will deadlock if _PyPclose is ever called by a thread
3746 * holding the global lock.
3747 */
3748
Fredrik Lundh56055a42000-07-23 19:47:12 +00003749static int _PyPclose(FILE *file)
3750{
Fredrik Lundh20318932000-07-26 17:29:12 +00003751 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003752 DWORD exit_code;
3753 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003754 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3755 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003756#ifdef WITH_THREAD
3757 PyInterpreterState* pInterpreterState;
3758 PyThreadState* pThreadState;
3759#endif
3760
Fredrik Lundh20318932000-07-26 17:29:12 +00003761 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003762 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003763 */
3764 result = fclose(file);
3765
Tim Peters736aa322000-09-01 06:51:24 +00003766#ifdef WITH_THREAD
3767 /* Bootstrap a valid thread state into existence. */
3768 pInterpreterState = PyInterpreterState_New();
3769 if (!pInterpreterState) {
3770 /* Well, we're hosed now! We don't have a thread
3771 * state, so can't call a nice error routine, or raise
3772 * an exception. Just die.
3773 */
3774 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003775 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003776 return -1; /* unreachable */
3777 }
3778 pThreadState = PyThreadState_New(pInterpreterState);
3779 if (!pThreadState) {
3780 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003781 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003782 return -1; /* unreachable */
3783 }
3784 /* Grab the global lock. Note that this will deadlock if the
3785 * current thread already has the lock! (see RED_FLAG comments
3786 * before this function)
3787 */
3788 PyEval_RestoreThread(pThreadState);
3789#endif
3790
Fredrik Lundh56055a42000-07-23 19:47:12 +00003791 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003792 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3793 (procObj = PyDict_GetItem(_PyPopenProcs,
3794 fileObj)) != NULL &&
3795 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3796 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3797
3798 hProcess = PyLong_AsVoidPtr(hProcessObj);
3799 file_count = PyInt_AsLong(intObj);
3800
3801 if (file_count > 1) {
3802 /* Still other files referencing process */
3803 file_count--;
3804 PyList_SetItem(procObj,1,
3805 PyInt_FromLong(file_count));
3806 } else {
3807 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003808 if (result != EOF &&
3809 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3810 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003811 /* Possible truncation here in 16-bit environments, but
3812 * real exit codes are just the lower byte in any event.
3813 */
3814 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003815 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003816 /* Indicate failure - this will cause the file object
3817 * to raise an I/O error and translate the last Win32
3818 * error code from errno. We do have a problem with
3819 * last errors that overlap the normal errno table,
3820 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003821 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003822 if (result != EOF) {
3823 /* If the error wasn't from the fclose(), then
3824 * set errno for the file object error handling.
3825 */
3826 errno = GetLastError();
3827 }
3828 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003829 }
3830
3831 /* Free up the native handle at this point */
3832 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003833 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003834
Mark Hammondb37a3732000-08-14 04:47:33 +00003835 /* Remove this file pointer from dictionary */
3836 PyDict_DelItem(_PyPopenProcs, fileObj);
3837
3838 if (PyDict_Size(_PyPopenProcs) == 0) {
3839 Py_DECREF(_PyPopenProcs);
3840 _PyPopenProcs = NULL;
3841 }
3842
3843 } /* if object retrieval ok */
3844
3845 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003846 } /* if _PyPopenProcs */
3847
Tim Peters736aa322000-09-01 06:51:24 +00003848#ifdef WITH_THREAD
3849 /* Tear down the thread & interpreter states.
3850 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003851 * call the thread clear & delete functions, and indeed insist on
3852 * doing that themselves. The lock must be held during the clear, but
3853 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003854 */
3855 PyInterpreterState_Clear(pInterpreterState);
3856 PyEval_ReleaseThread(pThreadState);
3857 PyInterpreterState_Delete(pInterpreterState);
3858#endif
3859
Fredrik Lundh56055a42000-07-23 19:47:12 +00003860 return result;
3861}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003862
3863#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003865posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003866{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003867 char *name;
3868 char *mode = "r";
3869 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003870 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003871 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003872 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003873 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003874 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003875 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003876 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003877 if (fp == NULL)
3878 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003879 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003880 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003881 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003882 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003883}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003884
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003885#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003886#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003888
Guido van Rossumb6775db1994-08-01 11:34:53 +00003889#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003890PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003891"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003892Set the current process's user id.");
3893
Barry Warsaw53699e91996-12-10 23:23:01 +00003894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003895posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003896{
3897 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003898 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003899 return NULL;
3900 if (setuid(uid) < 0)
3901 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003902 Py_INCREF(Py_None);
3903 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003904}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003905#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003907
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003908#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003909PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003910"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003911Set the current process's effective user id.");
3912
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003913static PyObject *
3914posix_seteuid (PyObject *self, PyObject *args)
3915{
3916 int euid;
3917 if (!PyArg_ParseTuple(args, "i", &euid)) {
3918 return NULL;
3919 } else if (seteuid(euid) < 0) {
3920 return posix_error();
3921 } else {
3922 Py_INCREF(Py_None);
3923 return Py_None;
3924 }
3925}
3926#endif /* HAVE_SETEUID */
3927
3928#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003929PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003930"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003931Set the current process's effective group id.");
3932
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003933static PyObject *
3934posix_setegid (PyObject *self, PyObject *args)
3935{
3936 int egid;
3937 if (!PyArg_ParseTuple(args, "i", &egid)) {
3938 return NULL;
3939 } else if (setegid(egid) < 0) {
3940 return posix_error();
3941 } else {
3942 Py_INCREF(Py_None);
3943 return Py_None;
3944 }
3945}
3946#endif /* HAVE_SETEGID */
3947
3948#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003949PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003950"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003951Set the current process's real and effective user ids.");
3952
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003953static PyObject *
3954posix_setreuid (PyObject *self, PyObject *args)
3955{
3956 int ruid, euid;
3957 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3958 return NULL;
3959 } else if (setreuid(ruid, euid) < 0) {
3960 return posix_error();
3961 } else {
3962 Py_INCREF(Py_None);
3963 return Py_None;
3964 }
3965}
3966#endif /* HAVE_SETREUID */
3967
3968#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003969PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003970"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003971Set the current process's real and effective group ids.");
3972
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003973static PyObject *
3974posix_setregid (PyObject *self, PyObject *args)
3975{
3976 int rgid, egid;
3977 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3978 return NULL;
3979 } else if (setregid(rgid, egid) < 0) {
3980 return posix_error();
3981 } else {
3982 Py_INCREF(Py_None);
3983 return Py_None;
3984 }
3985}
3986#endif /* HAVE_SETREGID */
3987
Guido van Rossumb6775db1994-08-01 11:34:53 +00003988#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003989PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003990"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003991Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003992
Barry Warsaw53699e91996-12-10 23:23:01 +00003993static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003994posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003995{
3996 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003997 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003998 return NULL;
3999 if (setgid(gid) < 0)
4000 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004001 Py_INCREF(Py_None);
4002 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004003}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004004#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004005
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004006#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004007PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004008"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004009Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004010
4011static PyObject *
4012posix_setgroups(PyObject *self, PyObject *args)
4013{
4014 PyObject *groups;
4015 int i, len;
4016 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004017
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004018 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4019 return NULL;
4020 if (!PySequence_Check(groups)) {
4021 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4022 return NULL;
4023 }
4024 len = PySequence_Size(groups);
4025 if (len > MAX_GROUPS) {
4026 PyErr_SetString(PyExc_ValueError, "too many groups");
4027 return NULL;
4028 }
4029 for(i = 0; i < len; i++) {
4030 PyObject *elem;
4031 elem = PySequence_GetItem(groups, i);
4032 if (!elem)
4033 return NULL;
4034 if (!PyInt_Check(elem)) {
4035 PyErr_SetString(PyExc_TypeError,
4036 "groups must be integers");
4037 Py_DECREF(elem);
4038 return NULL;
4039 }
4040 /* XXX: check that value fits into gid_t. */
4041 grouplist[i] = PyInt_AsLong(elem);
4042 Py_DECREF(elem);
4043 }
4044
4045 if (setgroups(len, grouplist) < 0)
4046 return posix_error();
4047 Py_INCREF(Py_None);
4048 return Py_None;
4049}
4050#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004051
Guido van Rossumb6775db1994-08-01 11:34:53 +00004052#ifdef HAVE_WAITPID
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)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004055Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004056
Barry Warsaw53699e91996-12-10 23:23:01 +00004057static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004058posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004059{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004060 int pid, options;
4061#ifdef UNION_WAIT
4062 union wait status;
4063#define status_i (status.w_status)
4064#else
4065 int status;
4066#define status_i status
4067#endif
4068 status_i = 0;
4069
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004070 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004071 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004072 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004073 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004074 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004075 if (pid == -1)
4076 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004077 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004078 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004079}
4080
Tim Petersab034fa2002-02-01 11:27:43 +00004081#elif defined(HAVE_CWAIT)
4082
4083/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004084PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004085"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004086"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004087
4088static PyObject *
4089posix_waitpid(PyObject *self, PyObject *args)
4090{
4091 int pid, options;
4092 int status;
4093
4094 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4095 return NULL;
4096 Py_BEGIN_ALLOW_THREADS
4097 pid = _cwait(&status, pid, options);
4098 Py_END_ALLOW_THREADS
4099 if (pid == -1)
4100 return posix_error();
4101 else
4102 /* shift the status left a byte so this is more like the
4103 POSIX waitpid */
4104 return Py_BuildValue("ii", pid, status << 8);
4105}
4106#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004107
Guido van Rossumad0ee831995-03-01 10:34:45 +00004108#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004109PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004110"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004111Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004112
Barry Warsaw53699e91996-12-10 23:23:01 +00004113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004114posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004115{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004116 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004117#ifdef UNION_WAIT
4118 union wait status;
4119#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004120#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004121 int status;
4122#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004123#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004124 if (!PyArg_ParseTuple(args, ":wait"))
4125 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004126 status_i = 0;
4127 Py_BEGIN_ALLOW_THREADS
4128 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004129 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004130 if (pid == -1)
4131 return posix_error();
4132 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004133 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004134#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004135}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004136#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004137
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004138
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004139PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004140"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004141Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004142
Barry Warsaw53699e91996-12-10 23:23:01 +00004143static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004144posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004145{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004146#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004147 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004148#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004149 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004150#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004151}
4152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004153
Guido van Rossumb6775db1994-08-01 11:34:53 +00004154#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004155PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004156"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004157Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004158
Barry Warsaw53699e91996-12-10 23:23:01 +00004159static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004160posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004161{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004162 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004163 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004164 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004165 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004166 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004167 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004168 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004169 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004170 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004171 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004172 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004173}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004174#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004176
Guido van Rossumb6775db1994-08-01 11:34:53 +00004177#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004178PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004179"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004180Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004181
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004183posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004184{
Mark Hammondef8b6542001-05-13 08:04:26 +00004185 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004186}
4187#endif /* HAVE_SYMLINK */
4188
4189
4190#ifdef HAVE_TIMES
4191#ifndef HZ
4192#define HZ 60 /* Universal constant :-) */
4193#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004194
Guido van Rossumd48f2521997-12-05 22:19:34 +00004195#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4196static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004197system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004198{
4199 ULONG value = 0;
4200
4201 Py_BEGIN_ALLOW_THREADS
4202 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4203 Py_END_ALLOW_THREADS
4204
4205 return value;
4206}
4207
4208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004209posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004210{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004211 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004212 return NULL;
4213
4214 /* Currently Only Uptime is Provided -- Others Later */
4215 return Py_BuildValue("ddddd",
4216 (double)0 /* t.tms_utime / HZ */,
4217 (double)0 /* t.tms_stime / HZ */,
4218 (double)0 /* t.tms_cutime / HZ */,
4219 (double)0 /* t.tms_cstime / HZ */,
4220 (double)system_uptime() / 1000);
4221}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004222#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004223static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004224posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004225{
4226 struct tms t;
4227 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004228 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004229 return NULL;
4230 errno = 0;
4231 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004232 if (c == (clock_t) -1)
4233 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004234 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004235 (double)t.tms_utime / HZ,
4236 (double)t.tms_stime / HZ,
4237 (double)t.tms_cutime / HZ,
4238 (double)t.tms_cstime / HZ,
4239 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004240}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004241#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004242#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004243
4244
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004245#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004246#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004247static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004248posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004249{
4250 FILETIME create, exit, kernel, user;
4251 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004252 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004253 return NULL;
4254 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004255 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4256 /* The fields of a FILETIME structure are the hi and lo part
4257 of a 64-bit value expressed in 100 nanosecond units.
4258 1e7 is one second in such units; 1e-7 the inverse.
4259 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4260 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004261 return Py_BuildValue(
4262 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004263 (double)(kernel.dwHighDateTime*429.4967296 +
4264 kernel.dwLowDateTime*1e-7),
4265 (double)(user.dwHighDateTime*429.4967296 +
4266 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004267 (double)0,
4268 (double)0,
4269 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004270}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004271#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004272
4273#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004274PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004275"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004276Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004277#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004279
Guido van Rossumb6775db1994-08-01 11:34:53 +00004280#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004281PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004282"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004283Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004284
Barry Warsaw53699e91996-12-10 23:23:01 +00004285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004286posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004287{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004288 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004289 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004290 if (setsid() < 0)
4291 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004292 Py_INCREF(Py_None);
4293 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004294}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004295#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004296
Guido van Rossumb6775db1994-08-01 11:34:53 +00004297#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004298PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004299"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004300Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004301
Barry Warsaw53699e91996-12-10 23:23:01 +00004302static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004303posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004304{
4305 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004306 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004307 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004308 if (setpgid(pid, pgrp) < 0)
4309 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004310 Py_INCREF(Py_None);
4311 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004312}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004313#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004314
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004315
Guido van Rossumb6775db1994-08-01 11:34:53 +00004316#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004317PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004318"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004319Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004320
Barry Warsaw53699e91996-12-10 23:23:01 +00004321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004322posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004323{
4324 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004325 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004326 return NULL;
4327 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004328 if (pgid < 0)
4329 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004330 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004331}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004332#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004333
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004334
Guido van Rossumb6775db1994-08-01 11:34:53 +00004335#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004336PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004337"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004338Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004339
Barry Warsaw53699e91996-12-10 23:23:01 +00004340static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004341posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004342{
4343 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004344 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004345 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004346 if (tcsetpgrp(fd, pgid) < 0)
4347 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004348 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004349 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004350}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004351#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004352
Guido van Rossum687dd131993-05-17 08:34:16 +00004353/* Functions acting on file descriptors */
4354
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004355PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004356"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004357Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004358
Barry Warsaw53699e91996-12-10 23:23:01 +00004359static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004360posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004361{
Mark Hammondef8b6542001-05-13 08:04:26 +00004362 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004363 int flag;
4364 int mode = 0777;
4365 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004366 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004367 Py_FileSystemDefaultEncoding, &file,
4368 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004369 return NULL;
4370
Barry Warsaw53699e91996-12-10 23:23:01 +00004371 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004372 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004373 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004374 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004375 return posix_error_with_allocated_filename(file);
4376 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004377 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004378}
4379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004380
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004381PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004382"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004383Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004384
Barry Warsaw53699e91996-12-10 23:23:01 +00004385static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004386posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004387{
4388 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004389 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004390 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004391 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004392 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004393 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004394 if (res < 0)
4395 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004396 Py_INCREF(Py_None);
4397 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004398}
4399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004400
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004401PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004402"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004403Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004404
Barry Warsaw53699e91996-12-10 23:23:01 +00004405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004406posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004407{
4408 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004409 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004410 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004411 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004412 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004413 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004414 if (fd < 0)
4415 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004416 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004417}
4418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004419
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004420PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004421"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004422Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004423
Barry Warsaw53699e91996-12-10 23:23:01 +00004424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004425posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004426{
4427 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004428 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004429 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004430 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004431 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004432 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004433 if (res < 0)
4434 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004435 Py_INCREF(Py_None);
4436 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004437}
4438
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004439
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004440PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004441"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004443
Barry Warsaw53699e91996-12-10 23:23:01 +00004444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004445posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004446{
4447 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004448#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004449 LONG_LONG pos, res;
4450#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004451 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004452#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004453 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004454 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004455 return NULL;
4456#ifdef SEEK_SET
4457 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4458 switch (how) {
4459 case 0: how = SEEK_SET; break;
4460 case 1: how = SEEK_CUR; break;
4461 case 2: how = SEEK_END; break;
4462 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004463#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004464
4465#if !defined(HAVE_LARGEFILE_SUPPORT)
4466 pos = PyInt_AsLong(posobj);
4467#else
4468 pos = PyLong_Check(posobj) ?
4469 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4470#endif
4471 if (PyErr_Occurred())
4472 return NULL;
4473
Barry Warsaw53699e91996-12-10 23:23:01 +00004474 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004475#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004476 res = _lseeki64(fd, pos, how);
4477#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004478 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004479#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004480 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004481 if (res < 0)
4482 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004483
4484#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004485 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004486#else
4487 return PyLong_FromLongLong(res);
4488#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004489}
4490
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004491
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004492PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004493"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004494Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004495
Barry Warsaw53699e91996-12-10 23:23:01 +00004496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004497posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004498{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004499 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004500 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004501 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004502 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004503 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004504 if (buffer == NULL)
4505 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004506 Py_BEGIN_ALLOW_THREADS
4507 n = read(fd, PyString_AsString(buffer), size);
4508 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004509 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004510 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004511 return posix_error();
4512 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004513 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004514 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004515 return buffer;
4516}
4517
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004518
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004519PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004520"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004521Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004522
Barry Warsaw53699e91996-12-10 23:23:01 +00004523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004524posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004525{
4526 int fd, size;
4527 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004528 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004529 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004530 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004531 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004532 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004533 if (size < 0)
4534 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004535 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004536}
4537
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004538
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004539PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004540"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004541Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004542
Barry Warsaw53699e91996-12-10 23:23:01 +00004543static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004544posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004545{
4546 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004547 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004548 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004549 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004550 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004551 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004552 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004553 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004554 if (res != 0)
4555 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004556
Fred Drake699f3522000-06-29 21:12:41 +00004557 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004558}
4559
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004560
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004561PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004562"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004563Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004564
Barry Warsaw53699e91996-12-10 23:23:01 +00004565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004566posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004567{
Guido van Rossum687dd131993-05-17 08:34:16 +00004568 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004569 char *mode = "r";
4570 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004571 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004572 PyObject *f;
4573 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004574 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004575
Barry Warsaw53699e91996-12-10 23:23:01 +00004576 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004577 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004578 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004579 if (fp == NULL)
4580 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00004581 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004582 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004583 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004584 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004585}
4586
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004587PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004588"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004589Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004590connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004591
4592static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004593posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004594{
4595 int fd;
4596 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4597 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004598 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004599}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004600
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004601#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004602PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004603"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004604Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004605
Barry Warsaw53699e91996-12-10 23:23:01 +00004606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004607posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004608{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004609#if defined(PYOS_OS2)
4610 HFILE read, write;
4611 APIRET rc;
4612
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004613 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004614 return NULL;
4615
4616 Py_BEGIN_ALLOW_THREADS
4617 rc = DosCreatePipe( &read, &write, 4096);
4618 Py_END_ALLOW_THREADS
4619 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004620 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004621
4622 return Py_BuildValue("(ii)", read, write);
4623#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004624#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004625 int fds[2];
4626 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004627 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004628 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004629 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004630 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004631 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004632 if (res != 0)
4633 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004634 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004635#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004636 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004637 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004638 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004639 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004640 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004641 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004642 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004643 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004644 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004645 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004646 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4647 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004648 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004649#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004650#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004651}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004652#endif /* HAVE_PIPE */
4653
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004654
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004655#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004656PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004657"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004658Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004659
Barry Warsaw53699e91996-12-10 23:23:01 +00004660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004661posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004662{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004663 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004664 int mode = 0666;
4665 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004666 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004667 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004668 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004669 res = mkfifo(filename, mode);
4670 Py_END_ALLOW_THREADS
4671 if (res < 0)
4672 return posix_error();
4673 Py_INCREF(Py_None);
4674 return Py_None;
4675}
4676#endif
4677
4678
Neal Norwitz11690112002-07-30 01:08:28 +00004679#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004680PyDoc_STRVAR(posix_mknod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004681"mknod(filename, [, mode=0600, major, minor])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004682Create a filesystem node (file, device special file or named pipe)\n\
4683named filename. mode specifies both the permissions to use and the\n\
4684type of node to be created, being combined (bitwise OR) with one of\n\
4685S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4686major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004687they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004688
4689
4690static PyObject *
4691posix_mknod(PyObject *self, PyObject *args)
4692{
4693 char *filename;
4694 int mode = 0600;
4695 int major = 0;
4696 int minor = 0;
4697 int res;
4698 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4699 &mode, &major, &minor))
4700 return NULL;
4701 Py_BEGIN_ALLOW_THREADS
4702 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004703 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004704 if (res < 0)
4705 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004706 Py_INCREF(Py_None);
4707 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004708}
4709#endif
4710
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004711
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004712#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004713PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004714"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004715Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004716
Barry Warsaw53699e91996-12-10 23:23:01 +00004717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004718posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004719{
4720 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004721 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004722 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004723 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004724
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004725 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004726 return NULL;
4727
4728#if !defined(HAVE_LARGEFILE_SUPPORT)
4729 length = PyInt_AsLong(lenobj);
4730#else
4731 length = PyLong_Check(lenobj) ?
4732 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4733#endif
4734 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004735 return NULL;
4736
Barry Warsaw53699e91996-12-10 23:23:01 +00004737 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004738 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004739 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004740 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004741 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004742 return NULL;
4743 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004744 Py_INCREF(Py_None);
4745 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004746}
4747#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004748
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004749#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004750PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004751"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004752Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004753
Fred Drake762e2061999-08-26 17:23:54 +00004754/* Save putenv() parameters as values here, so we can collect them when they
4755 * get re-set with another call for the same key. */
4756static PyObject *posix_putenv_garbage;
4757
Tim Peters5aa91602002-01-30 05:46:57 +00004758static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004759posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004760{
4761 char *s1, *s2;
4762 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004763 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004764 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004765
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004766 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004767 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004768
4769#if defined(PYOS_OS2)
4770 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4771 APIRET rc;
4772
4773 if (strlen(s2) == 0) /* If New Value is an Empty String */
4774 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4775
4776 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4777 if (rc != NO_ERROR)
4778 return os2_error(rc);
4779
4780 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4781 APIRET rc;
4782
4783 if (strlen(s2) == 0) /* If New Value is an Empty String */
4784 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4785
4786 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4787 if (rc != NO_ERROR)
4788 return os2_error(rc);
4789 } else {
4790#endif
4791
Fred Drake762e2061999-08-26 17:23:54 +00004792 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004793 len = strlen(s1) + strlen(s2) + 2;
4794 /* len includes space for a trailing \0; the size arg to
4795 PyString_FromStringAndSize does not count that */
4796 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004797 if (newstr == NULL)
4798 return PyErr_NoMemory();
4799 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004800 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004801 if (putenv(new)) {
4802 posix_error();
4803 return NULL;
4804 }
Fred Drake762e2061999-08-26 17:23:54 +00004805 /* Install the first arg and newstr in posix_putenv_garbage;
4806 * this will cause previous value to be collected. This has to
4807 * happen after the real putenv() call because the old value
4808 * was still accessible until then. */
4809 if (PyDict_SetItem(posix_putenv_garbage,
4810 PyTuple_GET_ITEM(args, 0), newstr)) {
4811 /* really not much we can do; just leak */
4812 PyErr_Clear();
4813 }
4814 else {
4815 Py_DECREF(newstr);
4816 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004817
4818#if defined(PYOS_OS2)
4819 }
4820#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004821 Py_INCREF(Py_None);
4822 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004823}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004824#endif /* putenv */
4825
Guido van Rossumc524d952001-10-19 01:31:59 +00004826#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004827PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004828"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004829Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00004830
4831static PyObject *
4832posix_unsetenv(PyObject *self, PyObject *args)
4833{
4834 char *s1;
4835
4836 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4837 return NULL;
4838
4839 unsetenv(s1);
4840
4841 /* Remove the key from posix_putenv_garbage;
4842 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004843 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004844 * old value was still accessible until then.
4845 */
4846 if (PyDict_DelItem(posix_putenv_garbage,
4847 PyTuple_GET_ITEM(args, 0))) {
4848 /* really not much we can do; just leak */
4849 PyErr_Clear();
4850 }
4851
4852 Py_INCREF(Py_None);
4853 return Py_None;
4854}
4855#endif /* unsetenv */
4856
Guido van Rossumb6a47161997-09-15 22:54:34 +00004857#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004858PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004859"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004860Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004861
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004862static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004863posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004864{
4865 int code;
4866 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004867 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004868 return NULL;
4869 message = strerror(code);
4870 if (message == NULL) {
4871 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004872 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004873 return NULL;
4874 }
4875 return PyString_FromString(message);
4876}
4877#endif /* strerror */
4878
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004879
Guido van Rossumc9641791998-08-04 15:26:23 +00004880#ifdef HAVE_SYS_WAIT_H
4881
Fred Drake106c1a02002-04-23 15:58:02 +00004882#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004883PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004884"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004885Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00004886
4887static PyObject *
4888posix_WCOREDUMP(PyObject *self, PyObject *args)
4889{
4890#ifdef UNION_WAIT
4891 union wait status;
4892#define status_i (status.w_status)
4893#else
4894 int status;
4895#define status_i status
4896#endif
4897 status_i = 0;
4898
4899 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4900 {
4901 return NULL;
4902 }
4903
4904 return PyBool_FromLong(WCOREDUMP(status));
4905#undef status_i
4906}
4907#endif /* WCOREDUMP */
4908
4909#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004910PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004911"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004912Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004913job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00004914
4915static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004916posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004917{
4918#ifdef UNION_WAIT
4919 union wait status;
4920#define status_i (status.w_status)
4921#else
4922 int status;
4923#define status_i status
4924#endif
4925 status_i = 0;
4926
4927 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4928 {
4929 return NULL;
4930 }
4931
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004932 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004933#undef status_i
4934}
4935#endif /* WIFCONTINUED */
4936
Guido van Rossumc9641791998-08-04 15:26:23 +00004937#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004938PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004939"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004940Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004941
4942static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004943posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004944{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004945#ifdef UNION_WAIT
4946 union wait status;
4947#define status_i (status.w_status)
4948#else
4949 int status;
4950#define status_i status
4951#endif
4952 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004953
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004954 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004955 {
4956 return NULL;
4957 }
Tim Peters5aa91602002-01-30 05:46:57 +00004958
Fred Drake106c1a02002-04-23 15:58:02 +00004959 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004960#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004961}
4962#endif /* WIFSTOPPED */
4963
4964#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004965PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004966"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004967Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004968
4969static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004970posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004971{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004972#ifdef UNION_WAIT
4973 union wait status;
4974#define status_i (status.w_status)
4975#else
4976 int status;
4977#define status_i status
4978#endif
4979 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004980
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004981 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004982 {
4983 return NULL;
4984 }
Tim Peters5aa91602002-01-30 05:46:57 +00004985
Fred Drake106c1a02002-04-23 15:58:02 +00004986 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004987#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004988}
4989#endif /* WIFSIGNALED */
4990
4991#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004992PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004993"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004994Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004995system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004996
4997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004998posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004999{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005000#ifdef UNION_WAIT
5001 union wait status;
5002#define status_i (status.w_status)
5003#else
5004 int status;
5005#define status_i status
5006#endif
5007 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005008
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005009 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005010 {
5011 return NULL;
5012 }
Tim Peters5aa91602002-01-30 05:46:57 +00005013
Fred Drake106c1a02002-04-23 15:58:02 +00005014 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005015#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005016}
5017#endif /* WIFEXITED */
5018
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005019#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005020PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005021"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005022Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005023
5024static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005025posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005026{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005027#ifdef UNION_WAIT
5028 union wait status;
5029#define status_i (status.w_status)
5030#else
5031 int status;
5032#define status_i status
5033#endif
5034 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005035
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005036 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005037 {
5038 return NULL;
5039 }
Tim Peters5aa91602002-01-30 05:46:57 +00005040
Guido van Rossumc9641791998-08-04 15:26:23 +00005041 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005042#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005043}
5044#endif /* WEXITSTATUS */
5045
5046#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005047PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005048"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005049Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005050value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005051
5052static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005053posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005054{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005055#ifdef UNION_WAIT
5056 union wait status;
5057#define status_i (status.w_status)
5058#else
5059 int status;
5060#define status_i status
5061#endif
5062 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005063
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005064 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005065 {
5066 return NULL;
5067 }
Tim Peters5aa91602002-01-30 05:46:57 +00005068
Guido van Rossumc9641791998-08-04 15:26:23 +00005069 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005070#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005071}
5072#endif /* WTERMSIG */
5073
5074#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005075PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005076"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005077Return the signal that stopped the process that provided\n\
5078the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005079
5080static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005081posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005082{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005083#ifdef UNION_WAIT
5084 union wait status;
5085#define status_i (status.w_status)
5086#else
5087 int status;
5088#define status_i status
5089#endif
5090 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005091
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005092 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005093 {
5094 return NULL;
5095 }
Tim Peters5aa91602002-01-30 05:46:57 +00005096
Guido van Rossumc9641791998-08-04 15:26:23 +00005097 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005098#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005099}
5100#endif /* WSTOPSIG */
5101
5102#endif /* HAVE_SYS_WAIT_H */
5103
5104
Guido van Rossum94f6f721999-01-06 18:42:14 +00005105#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005106#ifdef _SCO_DS
5107/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5108 needed definitions in sys/statvfs.h */
5109#define _SVID3
5110#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005111#include <sys/statvfs.h>
5112
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005113static PyObject*
5114_pystatvfs_fromstructstatvfs(struct statvfs st) {
5115 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5116 if (v == NULL)
5117 return NULL;
5118
5119#if !defined(HAVE_LARGEFILE_SUPPORT)
5120 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5121 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5122 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5123 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5124 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5125 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5126 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5127 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5128 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5129 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5130#else
5131 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5132 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005133 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005134 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005135 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005136 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5137 PyStructSequence_SET_ITEM(v, 4,
5138 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005139 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005140 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005141 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005142 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005143 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005144 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5145 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5146 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5147#endif
5148
5149 return v;
5150}
5151
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005152PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005153"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005154Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005155
5156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005157posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005158{
5159 int fd, res;
5160 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005161
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005162 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005163 return NULL;
5164 Py_BEGIN_ALLOW_THREADS
5165 res = fstatvfs(fd, &st);
5166 Py_END_ALLOW_THREADS
5167 if (res != 0)
5168 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005169
5170 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005171}
5172#endif /* HAVE_FSTATVFS */
5173
5174
5175#if defined(HAVE_STATVFS)
5176#include <sys/statvfs.h>
5177
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005178PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005179"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005180Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005181
5182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005183posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005184{
5185 char *path;
5186 int res;
5187 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005188 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005189 return NULL;
5190 Py_BEGIN_ALLOW_THREADS
5191 res = statvfs(path, &st);
5192 Py_END_ALLOW_THREADS
5193 if (res != 0)
5194 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005195
5196 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005197}
5198#endif /* HAVE_STATVFS */
5199
5200
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005201#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005202PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005203"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005204Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005205The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005206or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005207
5208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005209posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005210{
5211 PyObject *result = NULL;
5212 char *dir = NULL;
5213 char *pfx = NULL;
5214 char *name;
5215
5216 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5217 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005218
5219 if (PyErr_Warn(PyExc_RuntimeWarning,
5220 "tempnam is a potential security risk to your program") < 0)
5221 return NULL;
5222
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005223#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005224 name = _tempnam(dir, pfx);
5225#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005226 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005227#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005228 if (name == NULL)
5229 return PyErr_NoMemory();
5230 result = PyString_FromString(name);
5231 free(name);
5232 return result;
5233}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005234#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005235
5236
5237#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005238PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005239"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005240Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005241
5242static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005243posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005244{
5245 FILE *fp;
5246
5247 if (!PyArg_ParseTuple(args, ":tmpfile"))
5248 return NULL;
5249 fp = tmpfile();
5250 if (fp == NULL)
5251 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005252 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005253}
5254#endif
5255
5256
5257#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005258PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005259"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005260Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005261
5262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005263posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005264{
5265 char buffer[L_tmpnam];
5266 char *name;
5267
5268 if (!PyArg_ParseTuple(args, ":tmpnam"))
5269 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005270
5271 if (PyErr_Warn(PyExc_RuntimeWarning,
5272 "tmpnam is a potential security risk to your program") < 0)
5273 return NULL;
5274
Greg Wardb48bc172000-03-01 21:51:56 +00005275#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005276 name = tmpnam_r(buffer);
5277#else
5278 name = tmpnam(buffer);
5279#endif
5280 if (name == NULL) {
5281 PyErr_SetObject(PyExc_OSError,
5282 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005283#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005284 "unexpected NULL from tmpnam_r"
5285#else
5286 "unexpected NULL from tmpnam"
5287#endif
5288 ));
5289 return NULL;
5290 }
5291 return PyString_FromString(buffer);
5292}
5293#endif
5294
5295
Fred Drakec9680921999-12-13 16:37:25 +00005296/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5297 * It maps strings representing configuration variable names to
5298 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005299 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005300 * rarely-used constants. There are three separate tables that use
5301 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005302 *
5303 * This code is always included, even if none of the interfaces that
5304 * need it are included. The #if hackery needed to avoid it would be
5305 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005306 */
5307struct constdef {
5308 char *name;
5309 long value;
5310};
5311
Fred Drake12c6e2d1999-12-14 21:25:03 +00005312static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005313conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5314 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005315{
5316 if (PyInt_Check(arg)) {
5317 *valuep = PyInt_AS_LONG(arg);
5318 return 1;
5319 }
5320 if (PyString_Check(arg)) {
5321 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005322 size_t lo = 0;
5323 size_t mid;
5324 size_t hi = tablesize;
5325 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005326 char *confname = PyString_AS_STRING(arg);
5327 while (lo < hi) {
5328 mid = (lo + hi) / 2;
5329 cmp = strcmp(confname, table[mid].name);
5330 if (cmp < 0)
5331 hi = mid;
5332 else if (cmp > 0)
5333 lo = mid + 1;
5334 else {
5335 *valuep = table[mid].value;
5336 return 1;
5337 }
5338 }
5339 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5340 }
5341 else
5342 PyErr_SetString(PyExc_TypeError,
5343 "configuration names must be strings or integers");
5344 return 0;
5345}
5346
5347
5348#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5349static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005350#ifdef _PC_ABI_AIO_XFER_MAX
5351 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5352#endif
5353#ifdef _PC_ABI_ASYNC_IO
5354 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5355#endif
Fred Drakec9680921999-12-13 16:37:25 +00005356#ifdef _PC_ASYNC_IO
5357 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5358#endif
5359#ifdef _PC_CHOWN_RESTRICTED
5360 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5361#endif
5362#ifdef _PC_FILESIZEBITS
5363 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5364#endif
5365#ifdef _PC_LAST
5366 {"PC_LAST", _PC_LAST},
5367#endif
5368#ifdef _PC_LINK_MAX
5369 {"PC_LINK_MAX", _PC_LINK_MAX},
5370#endif
5371#ifdef _PC_MAX_CANON
5372 {"PC_MAX_CANON", _PC_MAX_CANON},
5373#endif
5374#ifdef _PC_MAX_INPUT
5375 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5376#endif
5377#ifdef _PC_NAME_MAX
5378 {"PC_NAME_MAX", _PC_NAME_MAX},
5379#endif
5380#ifdef _PC_NO_TRUNC
5381 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5382#endif
5383#ifdef _PC_PATH_MAX
5384 {"PC_PATH_MAX", _PC_PATH_MAX},
5385#endif
5386#ifdef _PC_PIPE_BUF
5387 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5388#endif
5389#ifdef _PC_PRIO_IO
5390 {"PC_PRIO_IO", _PC_PRIO_IO},
5391#endif
5392#ifdef _PC_SOCK_MAXBUF
5393 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5394#endif
5395#ifdef _PC_SYNC_IO
5396 {"PC_SYNC_IO", _PC_SYNC_IO},
5397#endif
5398#ifdef _PC_VDISABLE
5399 {"PC_VDISABLE", _PC_VDISABLE},
5400#endif
5401};
5402
Fred Drakec9680921999-12-13 16:37:25 +00005403static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005404conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005405{
5406 return conv_confname(arg, valuep, posix_constants_pathconf,
5407 sizeof(posix_constants_pathconf)
5408 / sizeof(struct constdef));
5409}
5410#endif
5411
5412#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005413PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005414"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005415Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005416If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005417
5418static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005419posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005420{
5421 PyObject *result = NULL;
5422 int name, fd;
5423
Fred Drake12c6e2d1999-12-14 21:25:03 +00005424 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5425 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005426 long limit;
5427
5428 errno = 0;
5429 limit = fpathconf(fd, name);
5430 if (limit == -1 && errno != 0)
5431 posix_error();
5432 else
5433 result = PyInt_FromLong(limit);
5434 }
5435 return result;
5436}
5437#endif
5438
5439
5440#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005441PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005442"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005443Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005444If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005445
5446static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005447posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005448{
5449 PyObject *result = NULL;
5450 int name;
5451 char *path;
5452
5453 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5454 conv_path_confname, &name)) {
5455 long limit;
5456
5457 errno = 0;
5458 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005459 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005460 if (errno == EINVAL)
5461 /* could be a path or name problem */
5462 posix_error();
5463 else
5464 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005465 }
Fred Drakec9680921999-12-13 16:37:25 +00005466 else
5467 result = PyInt_FromLong(limit);
5468 }
5469 return result;
5470}
5471#endif
5472
5473#ifdef HAVE_CONFSTR
5474static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005475#ifdef _CS_ARCHITECTURE
5476 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5477#endif
5478#ifdef _CS_HOSTNAME
5479 {"CS_HOSTNAME", _CS_HOSTNAME},
5480#endif
5481#ifdef _CS_HW_PROVIDER
5482 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5483#endif
5484#ifdef _CS_HW_SERIAL
5485 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5486#endif
5487#ifdef _CS_INITTAB_NAME
5488 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5489#endif
Fred Drakec9680921999-12-13 16:37:25 +00005490#ifdef _CS_LFS64_CFLAGS
5491 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5492#endif
5493#ifdef _CS_LFS64_LDFLAGS
5494 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5495#endif
5496#ifdef _CS_LFS64_LIBS
5497 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5498#endif
5499#ifdef _CS_LFS64_LINTFLAGS
5500 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5501#endif
5502#ifdef _CS_LFS_CFLAGS
5503 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5504#endif
5505#ifdef _CS_LFS_LDFLAGS
5506 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5507#endif
5508#ifdef _CS_LFS_LIBS
5509 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5510#endif
5511#ifdef _CS_LFS_LINTFLAGS
5512 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5513#endif
Fred Draked86ed291999-12-15 15:34:33 +00005514#ifdef _CS_MACHINE
5515 {"CS_MACHINE", _CS_MACHINE},
5516#endif
Fred Drakec9680921999-12-13 16:37:25 +00005517#ifdef _CS_PATH
5518 {"CS_PATH", _CS_PATH},
5519#endif
Fred Draked86ed291999-12-15 15:34:33 +00005520#ifdef _CS_RELEASE
5521 {"CS_RELEASE", _CS_RELEASE},
5522#endif
5523#ifdef _CS_SRPC_DOMAIN
5524 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5525#endif
5526#ifdef _CS_SYSNAME
5527 {"CS_SYSNAME", _CS_SYSNAME},
5528#endif
5529#ifdef _CS_VERSION
5530 {"CS_VERSION", _CS_VERSION},
5531#endif
Fred Drakec9680921999-12-13 16:37:25 +00005532#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5533 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5534#endif
5535#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5536 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5537#endif
5538#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5539 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5540#endif
5541#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5542 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5543#endif
5544#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5545 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5546#endif
5547#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5548 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5549#endif
5550#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5551 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5552#endif
5553#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5554 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5555#endif
5556#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5557 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5558#endif
5559#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5560 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5561#endif
5562#ifdef _CS_XBS5_LP64_OFF64_LIBS
5563 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5564#endif
5565#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5566 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5567#endif
5568#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5569 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5570#endif
5571#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5572 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5573#endif
5574#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5575 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5576#endif
5577#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5578 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5579#endif
Fred Draked86ed291999-12-15 15:34:33 +00005580#ifdef _MIPS_CS_AVAIL_PROCESSORS
5581 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5582#endif
5583#ifdef _MIPS_CS_BASE
5584 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5585#endif
5586#ifdef _MIPS_CS_HOSTID
5587 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5588#endif
5589#ifdef _MIPS_CS_HW_NAME
5590 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5591#endif
5592#ifdef _MIPS_CS_NUM_PROCESSORS
5593 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5594#endif
5595#ifdef _MIPS_CS_OSREL_MAJ
5596 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5597#endif
5598#ifdef _MIPS_CS_OSREL_MIN
5599 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5600#endif
5601#ifdef _MIPS_CS_OSREL_PATCH
5602 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5603#endif
5604#ifdef _MIPS_CS_OS_NAME
5605 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5606#endif
5607#ifdef _MIPS_CS_OS_PROVIDER
5608 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5609#endif
5610#ifdef _MIPS_CS_PROCESSORS
5611 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5612#endif
5613#ifdef _MIPS_CS_SERIAL
5614 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5615#endif
5616#ifdef _MIPS_CS_VENDOR
5617 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5618#endif
Fred Drakec9680921999-12-13 16:37:25 +00005619};
5620
5621static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005622conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005623{
5624 return conv_confname(arg, valuep, posix_constants_confstr,
5625 sizeof(posix_constants_confstr)
5626 / sizeof(struct constdef));
5627}
5628
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005629PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005630"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005631Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005632
5633static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005634posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005635{
5636 PyObject *result = NULL;
5637 int name;
5638 char buffer[64];
5639
5640 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5641 int len = confstr(name, buffer, sizeof(buffer));
5642
Fred Drakec9680921999-12-13 16:37:25 +00005643 errno = 0;
5644 if (len == 0) {
5645 if (errno != 0)
5646 posix_error();
5647 else
5648 result = PyString_FromString("");
5649 }
5650 else {
5651 if (len >= sizeof(buffer)) {
5652 result = PyString_FromStringAndSize(NULL, len);
5653 if (result != NULL)
5654 confstr(name, PyString_AS_STRING(result), len+1);
5655 }
5656 else
5657 result = PyString_FromString(buffer);
5658 }
5659 }
5660 return result;
5661}
5662#endif
5663
5664
5665#ifdef HAVE_SYSCONF
5666static struct constdef posix_constants_sysconf[] = {
5667#ifdef _SC_2_CHAR_TERM
5668 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5669#endif
5670#ifdef _SC_2_C_BIND
5671 {"SC_2_C_BIND", _SC_2_C_BIND},
5672#endif
5673#ifdef _SC_2_C_DEV
5674 {"SC_2_C_DEV", _SC_2_C_DEV},
5675#endif
5676#ifdef _SC_2_C_VERSION
5677 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5678#endif
5679#ifdef _SC_2_FORT_DEV
5680 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5681#endif
5682#ifdef _SC_2_FORT_RUN
5683 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5684#endif
5685#ifdef _SC_2_LOCALEDEF
5686 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5687#endif
5688#ifdef _SC_2_SW_DEV
5689 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5690#endif
5691#ifdef _SC_2_UPE
5692 {"SC_2_UPE", _SC_2_UPE},
5693#endif
5694#ifdef _SC_2_VERSION
5695 {"SC_2_VERSION", _SC_2_VERSION},
5696#endif
Fred Draked86ed291999-12-15 15:34:33 +00005697#ifdef _SC_ABI_ASYNCHRONOUS_IO
5698 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5699#endif
5700#ifdef _SC_ACL
5701 {"SC_ACL", _SC_ACL},
5702#endif
Fred Drakec9680921999-12-13 16:37:25 +00005703#ifdef _SC_AIO_LISTIO_MAX
5704 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5705#endif
Fred Drakec9680921999-12-13 16:37:25 +00005706#ifdef _SC_AIO_MAX
5707 {"SC_AIO_MAX", _SC_AIO_MAX},
5708#endif
5709#ifdef _SC_AIO_PRIO_DELTA_MAX
5710 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5711#endif
5712#ifdef _SC_ARG_MAX
5713 {"SC_ARG_MAX", _SC_ARG_MAX},
5714#endif
5715#ifdef _SC_ASYNCHRONOUS_IO
5716 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5717#endif
5718#ifdef _SC_ATEXIT_MAX
5719 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5720#endif
Fred Draked86ed291999-12-15 15:34:33 +00005721#ifdef _SC_AUDIT
5722 {"SC_AUDIT", _SC_AUDIT},
5723#endif
Fred Drakec9680921999-12-13 16:37:25 +00005724#ifdef _SC_AVPHYS_PAGES
5725 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5726#endif
5727#ifdef _SC_BC_BASE_MAX
5728 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5729#endif
5730#ifdef _SC_BC_DIM_MAX
5731 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5732#endif
5733#ifdef _SC_BC_SCALE_MAX
5734 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5735#endif
5736#ifdef _SC_BC_STRING_MAX
5737 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5738#endif
Fred Draked86ed291999-12-15 15:34:33 +00005739#ifdef _SC_CAP
5740 {"SC_CAP", _SC_CAP},
5741#endif
Fred Drakec9680921999-12-13 16:37:25 +00005742#ifdef _SC_CHARCLASS_NAME_MAX
5743 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5744#endif
5745#ifdef _SC_CHAR_BIT
5746 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5747#endif
5748#ifdef _SC_CHAR_MAX
5749 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5750#endif
5751#ifdef _SC_CHAR_MIN
5752 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5753#endif
5754#ifdef _SC_CHILD_MAX
5755 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5756#endif
5757#ifdef _SC_CLK_TCK
5758 {"SC_CLK_TCK", _SC_CLK_TCK},
5759#endif
5760#ifdef _SC_COHER_BLKSZ
5761 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5762#endif
5763#ifdef _SC_COLL_WEIGHTS_MAX
5764 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5765#endif
5766#ifdef _SC_DCACHE_ASSOC
5767 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5768#endif
5769#ifdef _SC_DCACHE_BLKSZ
5770 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5771#endif
5772#ifdef _SC_DCACHE_LINESZ
5773 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5774#endif
5775#ifdef _SC_DCACHE_SZ
5776 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5777#endif
5778#ifdef _SC_DCACHE_TBLKSZ
5779 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5780#endif
5781#ifdef _SC_DELAYTIMER_MAX
5782 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5783#endif
5784#ifdef _SC_EQUIV_CLASS_MAX
5785 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5786#endif
5787#ifdef _SC_EXPR_NEST_MAX
5788 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5789#endif
5790#ifdef _SC_FSYNC
5791 {"SC_FSYNC", _SC_FSYNC},
5792#endif
5793#ifdef _SC_GETGR_R_SIZE_MAX
5794 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5795#endif
5796#ifdef _SC_GETPW_R_SIZE_MAX
5797 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5798#endif
5799#ifdef _SC_ICACHE_ASSOC
5800 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5801#endif
5802#ifdef _SC_ICACHE_BLKSZ
5803 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5804#endif
5805#ifdef _SC_ICACHE_LINESZ
5806 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5807#endif
5808#ifdef _SC_ICACHE_SZ
5809 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5810#endif
Fred Draked86ed291999-12-15 15:34:33 +00005811#ifdef _SC_INF
5812 {"SC_INF", _SC_INF},
5813#endif
Fred Drakec9680921999-12-13 16:37:25 +00005814#ifdef _SC_INT_MAX
5815 {"SC_INT_MAX", _SC_INT_MAX},
5816#endif
5817#ifdef _SC_INT_MIN
5818 {"SC_INT_MIN", _SC_INT_MIN},
5819#endif
5820#ifdef _SC_IOV_MAX
5821 {"SC_IOV_MAX", _SC_IOV_MAX},
5822#endif
Fred Draked86ed291999-12-15 15:34:33 +00005823#ifdef _SC_IP_SECOPTS
5824 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5825#endif
Fred Drakec9680921999-12-13 16:37:25 +00005826#ifdef _SC_JOB_CONTROL
5827 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5828#endif
Fred Draked86ed291999-12-15 15:34:33 +00005829#ifdef _SC_KERN_POINTERS
5830 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5831#endif
5832#ifdef _SC_KERN_SIM
5833 {"SC_KERN_SIM", _SC_KERN_SIM},
5834#endif
Fred Drakec9680921999-12-13 16:37:25 +00005835#ifdef _SC_LINE_MAX
5836 {"SC_LINE_MAX", _SC_LINE_MAX},
5837#endif
5838#ifdef _SC_LOGIN_NAME_MAX
5839 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5840#endif
5841#ifdef _SC_LOGNAME_MAX
5842 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5843#endif
5844#ifdef _SC_LONG_BIT
5845 {"SC_LONG_BIT", _SC_LONG_BIT},
5846#endif
Fred Draked86ed291999-12-15 15:34:33 +00005847#ifdef _SC_MAC
5848 {"SC_MAC", _SC_MAC},
5849#endif
Fred Drakec9680921999-12-13 16:37:25 +00005850#ifdef _SC_MAPPED_FILES
5851 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5852#endif
5853#ifdef _SC_MAXPID
5854 {"SC_MAXPID", _SC_MAXPID},
5855#endif
5856#ifdef _SC_MB_LEN_MAX
5857 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5858#endif
5859#ifdef _SC_MEMLOCK
5860 {"SC_MEMLOCK", _SC_MEMLOCK},
5861#endif
5862#ifdef _SC_MEMLOCK_RANGE
5863 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5864#endif
5865#ifdef _SC_MEMORY_PROTECTION
5866 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5867#endif
5868#ifdef _SC_MESSAGE_PASSING
5869 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5870#endif
Fred Draked86ed291999-12-15 15:34:33 +00005871#ifdef _SC_MMAP_FIXED_ALIGNMENT
5872 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5873#endif
Fred Drakec9680921999-12-13 16:37:25 +00005874#ifdef _SC_MQ_OPEN_MAX
5875 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5876#endif
5877#ifdef _SC_MQ_PRIO_MAX
5878 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5879#endif
Fred Draked86ed291999-12-15 15:34:33 +00005880#ifdef _SC_NACLS_MAX
5881 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5882#endif
Fred Drakec9680921999-12-13 16:37:25 +00005883#ifdef _SC_NGROUPS_MAX
5884 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5885#endif
5886#ifdef _SC_NL_ARGMAX
5887 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5888#endif
5889#ifdef _SC_NL_LANGMAX
5890 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5891#endif
5892#ifdef _SC_NL_MSGMAX
5893 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5894#endif
5895#ifdef _SC_NL_NMAX
5896 {"SC_NL_NMAX", _SC_NL_NMAX},
5897#endif
5898#ifdef _SC_NL_SETMAX
5899 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5900#endif
5901#ifdef _SC_NL_TEXTMAX
5902 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5903#endif
5904#ifdef _SC_NPROCESSORS_CONF
5905 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5906#endif
5907#ifdef _SC_NPROCESSORS_ONLN
5908 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5909#endif
Fred Draked86ed291999-12-15 15:34:33 +00005910#ifdef _SC_NPROC_CONF
5911 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5912#endif
5913#ifdef _SC_NPROC_ONLN
5914 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5915#endif
Fred Drakec9680921999-12-13 16:37:25 +00005916#ifdef _SC_NZERO
5917 {"SC_NZERO", _SC_NZERO},
5918#endif
5919#ifdef _SC_OPEN_MAX
5920 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5921#endif
5922#ifdef _SC_PAGESIZE
5923 {"SC_PAGESIZE", _SC_PAGESIZE},
5924#endif
5925#ifdef _SC_PAGE_SIZE
5926 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5927#endif
5928#ifdef _SC_PASS_MAX
5929 {"SC_PASS_MAX", _SC_PASS_MAX},
5930#endif
5931#ifdef _SC_PHYS_PAGES
5932 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5933#endif
5934#ifdef _SC_PII
5935 {"SC_PII", _SC_PII},
5936#endif
5937#ifdef _SC_PII_INTERNET
5938 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5939#endif
5940#ifdef _SC_PII_INTERNET_DGRAM
5941 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5942#endif
5943#ifdef _SC_PII_INTERNET_STREAM
5944 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5945#endif
5946#ifdef _SC_PII_OSI
5947 {"SC_PII_OSI", _SC_PII_OSI},
5948#endif
5949#ifdef _SC_PII_OSI_CLTS
5950 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5951#endif
5952#ifdef _SC_PII_OSI_COTS
5953 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5954#endif
5955#ifdef _SC_PII_OSI_M
5956 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5957#endif
5958#ifdef _SC_PII_SOCKET
5959 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5960#endif
5961#ifdef _SC_PII_XTI
5962 {"SC_PII_XTI", _SC_PII_XTI},
5963#endif
5964#ifdef _SC_POLL
5965 {"SC_POLL", _SC_POLL},
5966#endif
5967#ifdef _SC_PRIORITIZED_IO
5968 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5969#endif
5970#ifdef _SC_PRIORITY_SCHEDULING
5971 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5972#endif
5973#ifdef _SC_REALTIME_SIGNALS
5974 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5975#endif
5976#ifdef _SC_RE_DUP_MAX
5977 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5978#endif
5979#ifdef _SC_RTSIG_MAX
5980 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5981#endif
5982#ifdef _SC_SAVED_IDS
5983 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5984#endif
5985#ifdef _SC_SCHAR_MAX
5986 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5987#endif
5988#ifdef _SC_SCHAR_MIN
5989 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5990#endif
5991#ifdef _SC_SELECT
5992 {"SC_SELECT", _SC_SELECT},
5993#endif
5994#ifdef _SC_SEMAPHORES
5995 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5996#endif
5997#ifdef _SC_SEM_NSEMS_MAX
5998 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5999#endif
6000#ifdef _SC_SEM_VALUE_MAX
6001 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6002#endif
6003#ifdef _SC_SHARED_MEMORY_OBJECTS
6004 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6005#endif
6006#ifdef _SC_SHRT_MAX
6007 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6008#endif
6009#ifdef _SC_SHRT_MIN
6010 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6011#endif
6012#ifdef _SC_SIGQUEUE_MAX
6013 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6014#endif
6015#ifdef _SC_SIGRT_MAX
6016 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6017#endif
6018#ifdef _SC_SIGRT_MIN
6019 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6020#endif
Fred Draked86ed291999-12-15 15:34:33 +00006021#ifdef _SC_SOFTPOWER
6022 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6023#endif
Fred Drakec9680921999-12-13 16:37:25 +00006024#ifdef _SC_SPLIT_CACHE
6025 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6026#endif
6027#ifdef _SC_SSIZE_MAX
6028 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6029#endif
6030#ifdef _SC_STACK_PROT
6031 {"SC_STACK_PROT", _SC_STACK_PROT},
6032#endif
6033#ifdef _SC_STREAM_MAX
6034 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6035#endif
6036#ifdef _SC_SYNCHRONIZED_IO
6037 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6038#endif
6039#ifdef _SC_THREADS
6040 {"SC_THREADS", _SC_THREADS},
6041#endif
6042#ifdef _SC_THREAD_ATTR_STACKADDR
6043 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6044#endif
6045#ifdef _SC_THREAD_ATTR_STACKSIZE
6046 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6047#endif
6048#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6049 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6050#endif
6051#ifdef _SC_THREAD_KEYS_MAX
6052 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6053#endif
6054#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6055 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6056#endif
6057#ifdef _SC_THREAD_PRIO_INHERIT
6058 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6059#endif
6060#ifdef _SC_THREAD_PRIO_PROTECT
6061 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6062#endif
6063#ifdef _SC_THREAD_PROCESS_SHARED
6064 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6065#endif
6066#ifdef _SC_THREAD_SAFE_FUNCTIONS
6067 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6068#endif
6069#ifdef _SC_THREAD_STACK_MIN
6070 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6071#endif
6072#ifdef _SC_THREAD_THREADS_MAX
6073 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6074#endif
6075#ifdef _SC_TIMERS
6076 {"SC_TIMERS", _SC_TIMERS},
6077#endif
6078#ifdef _SC_TIMER_MAX
6079 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6080#endif
6081#ifdef _SC_TTY_NAME_MAX
6082 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6083#endif
6084#ifdef _SC_TZNAME_MAX
6085 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6086#endif
6087#ifdef _SC_T_IOV_MAX
6088 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6089#endif
6090#ifdef _SC_UCHAR_MAX
6091 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6092#endif
6093#ifdef _SC_UINT_MAX
6094 {"SC_UINT_MAX", _SC_UINT_MAX},
6095#endif
6096#ifdef _SC_UIO_MAXIOV
6097 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6098#endif
6099#ifdef _SC_ULONG_MAX
6100 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6101#endif
6102#ifdef _SC_USHRT_MAX
6103 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6104#endif
6105#ifdef _SC_VERSION
6106 {"SC_VERSION", _SC_VERSION},
6107#endif
6108#ifdef _SC_WORD_BIT
6109 {"SC_WORD_BIT", _SC_WORD_BIT},
6110#endif
6111#ifdef _SC_XBS5_ILP32_OFF32
6112 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6113#endif
6114#ifdef _SC_XBS5_ILP32_OFFBIG
6115 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6116#endif
6117#ifdef _SC_XBS5_LP64_OFF64
6118 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6119#endif
6120#ifdef _SC_XBS5_LPBIG_OFFBIG
6121 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6122#endif
6123#ifdef _SC_XOPEN_CRYPT
6124 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6125#endif
6126#ifdef _SC_XOPEN_ENH_I18N
6127 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6128#endif
6129#ifdef _SC_XOPEN_LEGACY
6130 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6131#endif
6132#ifdef _SC_XOPEN_REALTIME
6133 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6134#endif
6135#ifdef _SC_XOPEN_REALTIME_THREADS
6136 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6137#endif
6138#ifdef _SC_XOPEN_SHM
6139 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6140#endif
6141#ifdef _SC_XOPEN_UNIX
6142 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6143#endif
6144#ifdef _SC_XOPEN_VERSION
6145 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6146#endif
6147#ifdef _SC_XOPEN_XCU_VERSION
6148 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6149#endif
6150#ifdef _SC_XOPEN_XPG2
6151 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6152#endif
6153#ifdef _SC_XOPEN_XPG3
6154 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6155#endif
6156#ifdef _SC_XOPEN_XPG4
6157 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6158#endif
6159};
6160
6161static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006162conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006163{
6164 return conv_confname(arg, valuep, posix_constants_sysconf,
6165 sizeof(posix_constants_sysconf)
6166 / sizeof(struct constdef));
6167}
6168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006169PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006170"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006171Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006172
6173static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006174posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006175{
6176 PyObject *result = NULL;
6177 int name;
6178
6179 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6180 int value;
6181
6182 errno = 0;
6183 value = sysconf(name);
6184 if (value == -1 && errno != 0)
6185 posix_error();
6186 else
6187 result = PyInt_FromLong(value);
6188 }
6189 return result;
6190}
6191#endif
6192
6193
Fred Drakebec628d1999-12-15 18:31:10 +00006194/* This code is used to ensure that the tables of configuration value names
6195 * are in sorted order as required by conv_confname(), and also to build the
6196 * the exported dictionaries that are used to publish information about the
6197 * names available on the host platform.
6198 *
6199 * Sorting the table at runtime ensures that the table is properly ordered
6200 * when used, even for platforms we're not able to test on. It also makes
6201 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006202 */
Fred Drakebec628d1999-12-15 18:31:10 +00006203
6204static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006205cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006206{
6207 const struct constdef *c1 =
6208 (const struct constdef *) v1;
6209 const struct constdef *c2 =
6210 (const struct constdef *) v2;
6211
6212 return strcmp(c1->name, c2->name);
6213}
6214
6215static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006216setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006217 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006218{
Fred Drakebec628d1999-12-15 18:31:10 +00006219 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006220 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006221
6222 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6223 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006224 if (d == NULL)
6225 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006226
Barry Warsaw3155db32000-04-13 15:20:40 +00006227 for (i=0; i < tablesize; ++i) {
6228 PyObject *o = PyInt_FromLong(table[i].value);
6229 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6230 Py_XDECREF(o);
6231 Py_DECREF(d);
6232 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006233 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006234 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006235 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006236 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006237}
6238
Fred Drakebec628d1999-12-15 18:31:10 +00006239/* Return -1 on failure, 0 on success. */
6240static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006241setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006242{
6243#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006244 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006245 sizeof(posix_constants_pathconf)
6246 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006247 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006248 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006249#endif
6250#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006251 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006252 sizeof(posix_constants_confstr)
6253 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006254 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006255 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006256#endif
6257#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006258 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006259 sizeof(posix_constants_sysconf)
6260 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006261 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006262 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006263#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006264 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006265}
Fred Draked86ed291999-12-15 15:34:33 +00006266
6267
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006268PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006269"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006270Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006271in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006272
6273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006274posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006275{
6276 if (!PyArg_ParseTuple(args, ":abort"))
6277 return NULL;
6278 abort();
6279 /*NOTREACHED*/
6280 Py_FatalError("abort() called from Python code didn't abort!");
6281 return NULL;
6282}
Fred Drakebec628d1999-12-15 18:31:10 +00006283
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006284#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006285PyDoc_STRVAR(win32_startfile__doc__,
6286"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006287\n\
6288This acts like double-clicking the file in Explorer, or giving the file\n\
6289name as an argument to the DOS \"start\" command: the file is opened\n\
6290with whatever application (if any) its extension is associated.\n\
6291\n\
6292startfile returns as soon as the associated application is launched.\n\
6293There is no option to wait for the application to close, and no way\n\
6294to retrieve the application's exit status.\n\
6295\n\
6296The filepath is relative to the current directory. If you want to use\n\
6297an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006298the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006299
6300static PyObject *
6301win32_startfile(PyObject *self, PyObject *args)
6302{
6303 char *filepath;
6304 HINSTANCE rc;
6305 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6306 return NULL;
6307 Py_BEGIN_ALLOW_THREADS
6308 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6309 Py_END_ALLOW_THREADS
6310 if (rc <= (HINSTANCE)32)
6311 return win32_error("startfile", filepath);
6312 Py_INCREF(Py_None);
6313 return Py_None;
6314}
6315#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006316
6317static PyMethodDef posix_methods[] = {
6318 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6319#ifdef HAVE_TTYNAME
6320 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6321#endif
6322 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6323 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006324#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006325 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006326#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006327#ifdef HAVE_LCHOWN
6328 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6329#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006330#ifdef HAVE_CHROOT
6331 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6332#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006333#ifdef HAVE_CTERMID
6334 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6335#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006336#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006337 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006338#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006339#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006340 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006341#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006342 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6343 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6344 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006345#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006346 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006347#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006348#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006349 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006350#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006351 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6352 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6353 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006354#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006355 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006356#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006357#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006358 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006359#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006360 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006361#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006362 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006363#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006364 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6365 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6366 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006367#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006368 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006369#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006370 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006371#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006372 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6373 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006374#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006375#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006376 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6377 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006378#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006379#ifdef HAVE_FORK1
6380 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6381#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006382#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006383 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006384#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006385#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006386 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006387#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006388#ifdef HAVE_FORKPTY
6389 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6390#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006391#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006392 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006393#endif /* HAVE_GETEGID */
6394#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006395 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006396#endif /* HAVE_GETEUID */
6397#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006398 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006399#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006400#ifdef HAVE_GETGROUPS
6401 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6402#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006403 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006404#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006405 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006406#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006407#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006408 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006409#endif /* HAVE_GETPPID */
6410#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006411 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006412#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006413#ifdef HAVE_GETLOGIN
6414 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6415#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006416#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006417 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006418#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006419#ifdef HAVE_KILLPG
6420 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6421#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006422#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006423 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006424#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006425#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006426 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006427#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006428 {"popen2", win32_popen2, METH_VARARGS},
6429 {"popen3", win32_popen3, METH_VARARGS},
6430 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006431 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006432#else
6433#if defined(PYOS_OS2) && defined(PYCC_GCC)
6434 {"popen2", os2emx_popen2, METH_VARARGS},
6435 {"popen3", os2emx_popen3, METH_VARARGS},
6436 {"popen4", os2emx_popen4, METH_VARARGS},
6437#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006438#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006439#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006440#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006441 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006442#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006443#ifdef HAVE_SETEUID
6444 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6445#endif /* HAVE_SETEUID */
6446#ifdef HAVE_SETEGID
6447 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6448#endif /* HAVE_SETEGID */
6449#ifdef HAVE_SETREUID
6450 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6451#endif /* HAVE_SETREUID */
6452#ifdef HAVE_SETREGID
6453 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6454#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006455#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006456 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006457#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006458#ifdef HAVE_SETGROUPS
6459 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6460#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006461#ifdef HAVE_GETPGID
6462 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6463#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006464#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006465 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006466#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006467#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006468 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006469#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006470#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006471 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006472#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006473#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006474 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006475#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006476#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006477 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006478#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006479#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006480 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006481#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006482#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006483 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006484#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006485 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6486 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6487 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6488 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6489 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6490 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6491 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6492 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6493 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006494 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006495#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006496 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006497#endif
6498#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006499 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006500#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006501#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006502 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6503#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006504#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006505 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006506#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006507#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006508 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006509#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006510#ifdef HAVE_UNSETENV
6511 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6512#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006513#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006514 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006515#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006516#ifdef HAVE_FCHDIR
6517 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6518#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006519#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006520 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006521#endif
6522#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006523 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006524#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006525#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006526#ifdef WCOREDUMP
6527 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6528#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006529#ifdef WIFCONTINUED
6530 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6531#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006532#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006533 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006534#endif /* WIFSTOPPED */
6535#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006536 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006537#endif /* WIFSIGNALED */
6538#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006539 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006540#endif /* WIFEXITED */
6541#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006542 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006543#endif /* WEXITSTATUS */
6544#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006545 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006546#endif /* WTERMSIG */
6547#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006548 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006549#endif /* WSTOPSIG */
6550#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006551#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006552 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006553#endif
6554#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006555 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006556#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006557#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006558 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6559#endif
6560#ifdef HAVE_TEMPNAM
6561 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6562#endif
6563#ifdef HAVE_TMPNAM
6564 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6565#endif
Fred Drakec9680921999-12-13 16:37:25 +00006566#ifdef HAVE_CONFSTR
6567 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6568#endif
6569#ifdef HAVE_SYSCONF
6570 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6571#endif
6572#ifdef HAVE_FPATHCONF
6573 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6574#endif
6575#ifdef HAVE_PATHCONF
6576 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6577#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006578 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006579#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006580 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6581#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006582 {NULL, NULL} /* Sentinel */
6583};
6584
6585
Barry Warsaw4a342091996-12-19 23:50:02 +00006586static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006587ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006588{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006589 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006590}
6591
Guido van Rossumd48f2521997-12-05 22:19:34 +00006592#if defined(PYOS_OS2)
6593/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006594static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006595{
6596 APIRET rc;
6597 ULONG values[QSV_MAX+1];
6598 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006599 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006600
6601 Py_BEGIN_ALLOW_THREADS
6602 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6603 Py_END_ALLOW_THREADS
6604
6605 if (rc != NO_ERROR) {
6606 os2_error(rc);
6607 return -1;
6608 }
6609
Fred Drake4d1e64b2002-04-15 19:40:07 +00006610 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6611 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6612 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6613 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6614 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6615 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6616 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006617
6618 switch (values[QSV_VERSION_MINOR]) {
6619 case 0: ver = "2.00"; break;
6620 case 10: ver = "2.10"; break;
6621 case 11: ver = "2.11"; break;
6622 case 30: ver = "3.00"; break;
6623 case 40: ver = "4.00"; break;
6624 case 50: ver = "5.00"; break;
6625 default:
Tim Peters885d4572001-11-28 20:27:42 +00006626 PyOS_snprintf(tmp, sizeof(tmp),
6627 "%d-%d", values[QSV_VERSION_MAJOR],
6628 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006629 ver = &tmp[0];
6630 }
6631
6632 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006633 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006634 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006635
6636 /* Add Indicator of Which Drive was Used to Boot the System */
6637 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6638 tmp[1] = ':';
6639 tmp[2] = '\0';
6640
Fred Drake4d1e64b2002-04-15 19:40:07 +00006641 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006642}
6643#endif
6644
Barry Warsaw4a342091996-12-19 23:50:02 +00006645static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006646all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006647{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006648#ifdef F_OK
6649 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006650#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006651#ifdef R_OK
6652 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006653#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006654#ifdef W_OK
6655 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006656#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006657#ifdef X_OK
6658 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006659#endif
Fred Drakec9680921999-12-13 16:37:25 +00006660#ifdef NGROUPS_MAX
6661 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6662#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006663#ifdef TMP_MAX
6664 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6665#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006666#ifdef WCONTINUED
6667 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6668#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006669#ifdef WNOHANG
6670 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006671#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006672#ifdef WUNTRACED
6673 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6674#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006675#ifdef O_RDONLY
6676 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6677#endif
6678#ifdef O_WRONLY
6679 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6680#endif
6681#ifdef O_RDWR
6682 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6683#endif
6684#ifdef O_NDELAY
6685 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6686#endif
6687#ifdef O_NONBLOCK
6688 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6689#endif
6690#ifdef O_APPEND
6691 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6692#endif
6693#ifdef O_DSYNC
6694 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6695#endif
6696#ifdef O_RSYNC
6697 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6698#endif
6699#ifdef O_SYNC
6700 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6701#endif
6702#ifdef O_NOCTTY
6703 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6704#endif
6705#ifdef O_CREAT
6706 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6707#endif
6708#ifdef O_EXCL
6709 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6710#endif
6711#ifdef O_TRUNC
6712 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6713#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006714#ifdef O_BINARY
6715 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6716#endif
6717#ifdef O_TEXT
6718 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6719#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006720#ifdef O_LARGEFILE
6721 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6722#endif
6723
Tim Peters5aa91602002-01-30 05:46:57 +00006724/* MS Windows */
6725#ifdef O_NOINHERIT
6726 /* Don't inherit in child processes. */
6727 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6728#endif
6729#ifdef _O_SHORT_LIVED
6730 /* Optimize for short life (keep in memory). */
6731 /* MS forgot to define this one with a non-underscore form too. */
6732 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6733#endif
6734#ifdef O_TEMPORARY
6735 /* Automatically delete when last handle is closed. */
6736 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6737#endif
6738#ifdef O_RANDOM
6739 /* Optimize for random access. */
6740 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6741#endif
6742#ifdef O_SEQUENTIAL
6743 /* Optimize for sequential access. */
6744 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6745#endif
6746
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006747/* GNU extensions. */
6748#ifdef O_DIRECT
6749 /* Direct disk access. */
6750 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6751#endif
6752#ifdef O_DIRECTORY
6753 /* Must be a directory. */
6754 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6755#endif
6756#ifdef O_NOFOLLOW
6757 /* Do not follow links. */
6758 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6759#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006760
Guido van Rossum246bc171999-02-01 23:54:31 +00006761#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006762#if defined(PYOS_OS2) && defined(PYCC_GCC)
6763 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6764 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6765 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6766 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6767 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6768 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6769 if (ins(d, "P_PM", (long)P_PM)) return -1;
6770 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6771 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6772 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6773 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6774 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6775 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6776 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6777 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6778 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6779 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6780 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6781 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6782 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6783#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006784 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6785 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6786 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6787 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6788 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006789#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006790#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006791
Guido van Rossumd48f2521997-12-05 22:19:34 +00006792#if defined(PYOS_OS2)
6793 if (insertvalues(d)) return -1;
6794#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006795 return 0;
6796}
6797
6798
Tim Peters5aa91602002-01-30 05:46:57 +00006799#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006800#define INITFUNC initnt
6801#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006802
6803#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006804#define INITFUNC initos2
6805#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006806
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006807#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006808#define INITFUNC initposix
6809#define MODNAME "posix"
6810#endif
6811
Mark Hammondfe51c6d2002-08-02 02:27:13 +00006812PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006813INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006814{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006815 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006816
Fred Drake4d1e64b2002-04-15 19:40:07 +00006817 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006818 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006819 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006820
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006821 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006822 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006823 Py_XINCREF(v);
6824 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006825 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006826 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006827
Fred Drake4d1e64b2002-04-15 19:40:07 +00006828 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006829 return;
6830
Fred Drake4d1e64b2002-04-15 19:40:07 +00006831 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006832 return;
6833
Fred Drake4d1e64b2002-04-15 19:40:07 +00006834 Py_INCREF(PyExc_OSError);
6835 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006836
Guido van Rossumb3d39562000-01-31 18:41:26 +00006837#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006838 if (posix_putenv_garbage == NULL)
6839 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006840#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006841
Guido van Rossum14648392001-12-08 18:02:58 +00006842 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006843 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006844 Py_INCREF((PyObject*) &StatResultType);
6845 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006846
Guido van Rossum14648392001-12-08 18:02:58 +00006847 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006848 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006849 Py_INCREF((PyObject*) &StatVFSResultType);
6850 PyModule_AddObject(m, "statvfs_result",
6851 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006852}