blob: e442e7907b34177a613c0a0893aa9679944471d2 [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;
1415 *usec = (tval - intval) * 1e6;
1416 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;
1427}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001429PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001430"utime(path, (atime, utime))\n\
1431utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001432Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001433second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001434
Barry Warsaw53699e91996-12-10 23:23:01 +00001435static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001436posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001437{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001438 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001439 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001440 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001441 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001442
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001443#if defined(HAVE_UTIMES)
1444 struct timeval buf[2];
1445#define ATIME buf[0].tv_sec
1446#define MTIME buf[1].tv_sec
1447#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001448/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001449 struct utimbuf buf;
1450#define ATIME buf.actime
1451#define MTIME buf.modtime
1452#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001453#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001454 time_t buf[2];
1455#define ATIME buf[0]
1456#define MTIME buf[1]
1457#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001458#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001459
Barry Warsaw3cef8562000-05-01 16:17:24 +00001460 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001461 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001462 if (arg == Py_None) {
1463 /* optional time values not given */
1464 Py_BEGIN_ALLOW_THREADS
1465 res = utime(path, NULL);
1466 Py_END_ALLOW_THREADS
1467 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001468 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001469 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001470 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001471 return NULL;
1472 }
1473 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001474 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1475 &atime, &ausec) == -1)
1476 return NULL;
1477 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1478 &mtime, &musec) == -1)
1479 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001480 ATIME = atime;
1481 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001482#ifdef HAVE_UTIMES
1483 buf[0].tv_usec = ausec;
1484 buf[1].tv_usec = musec;
1485 Py_BEGIN_ALLOW_THREADS
1486 res = utimes(path, buf);
1487 Py_END_ALLOW_THREADS
1488#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001489 Py_BEGIN_ALLOW_THREADS
1490 res = utime(path, UTIME_ARG);
1491 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001492#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00001493 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001494 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001495 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001496 Py_INCREF(Py_None);
1497 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001498#undef UTIME_ARG
1499#undef ATIME
1500#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001501}
1502
Guido van Rossum85e3b011991-06-03 12:42:10 +00001503
Guido van Rossum3b066191991-06-04 19:40:25 +00001504/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001505
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001506PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001507"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001508Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001509
Barry Warsaw53699e91996-12-10 23:23:01 +00001510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001511posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001512{
1513 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001514 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001515 return NULL;
1516 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001517 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001518}
1519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001520
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001521#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001522PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001523"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001524Execute an executable path with arguments, replacing current process.\n\
1525\n\
1526 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001527 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001528
Barry Warsaw53699e91996-12-10 23:23:01 +00001529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001530posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001531{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001532 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001533 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001534 char **argvlist;
1535 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001536 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001537
Guido van Rossum89b33251993-10-22 14:26:06 +00001538 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001539 argv is a list or tuple of strings. */
1540
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001541 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001542 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001543 if (PyList_Check(argv)) {
1544 argc = PyList_Size(argv);
1545 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001546 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001547 else if (PyTuple_Check(argv)) {
1548 argc = PyTuple_Size(argv);
1549 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001550 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001551 else {
Fred Drake661ea262000-10-24 19:57:45 +00001552 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001553 return NULL;
1554 }
1555
1556 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001557 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001558 return NULL;
1559 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001560
Barry Warsaw53699e91996-12-10 23:23:01 +00001561 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001562 if (argvlist == NULL)
1563 return NULL;
1564 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001565 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1566 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001567 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001568 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001569 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001570
Guido van Rossum85e3b011991-06-03 12:42:10 +00001571 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001572 }
1573 argvlist[argc] = NULL;
1574
Guido van Rossumb6775db1994-08-01 11:34:53 +00001575#ifdef BAD_EXEC_PROTOTYPES
1576 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001577#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001578 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001579#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001580
Guido van Rossum85e3b011991-06-03 12:42:10 +00001581 /* If we get here it's definitely an error */
1582
Barry Warsaw53699e91996-12-10 23:23:01 +00001583 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001584 return posix_error();
1585}
1586
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001587
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001588PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001589"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001590Execute a path with arguments and environment, replacing current process.\n\
1591\n\
1592 path: path of executable file\n\
1593 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001594 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001595
Barry Warsaw53699e91996-12-10 23:23:01 +00001596static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001597posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001598{
1599 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001600 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001601 char **argvlist;
1602 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001603 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001604 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001605 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001606
1607 /* execve has three arguments: (path, argv, env), where
1608 argv is a list or tuple of strings and env is a dictionary
1609 like posix.environ. */
1610
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001611 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001612 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001613 if (PyList_Check(argv)) {
1614 argc = PyList_Size(argv);
1615 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001616 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001617 else if (PyTuple_Check(argv)) {
1618 argc = PyTuple_Size(argv);
1619 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001620 }
1621 else {
Fred Drake661ea262000-10-24 19:57:45 +00001622 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001623 return NULL;
1624 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001625 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001626 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001627 return NULL;
1628 }
1629
Guido van Rossum50422b42000-04-26 20:34:28 +00001630 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001631 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001632 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001633 return NULL;
1634 }
1635
Barry Warsaw53699e91996-12-10 23:23:01 +00001636 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001637 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001638 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001639 return NULL;
1640 }
1641 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001642 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001643 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001644 &argvlist[i]))
1645 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001646 goto fail_1;
1647 }
1648 }
1649 argvlist[argc] = NULL;
1650
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001651 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001652 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001653 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001654 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001655 goto fail_1;
1656 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001657 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001658 keys = PyMapping_Keys(env);
1659 vals = PyMapping_Values(env);
1660 if (!keys || !vals)
1661 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001662
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001663 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001664 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001665 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001666
1667 key = PyList_GetItem(keys, pos);
1668 val = PyList_GetItem(vals, pos);
1669 if (!key || !val)
1670 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001671
Fred Drake661ea262000-10-24 19:57:45 +00001672 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1673 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001674 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001675 goto fail_2;
1676 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001677
1678#if defined(PYOS_OS2)
1679 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1680 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1681#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001682 len = PyString_Size(key) + PyString_Size(val) + 2;
1683 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001684 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001685 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001686 goto fail_2;
1687 }
Tim Petersc8996f52001-12-03 20:41:00 +00001688 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001689 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001690#if defined(PYOS_OS2)
1691 }
1692#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001693 }
1694 envlist[envc] = 0;
1695
Guido van Rossumb6775db1994-08-01 11:34:53 +00001696
1697#ifdef BAD_EXEC_PROTOTYPES
1698 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001699#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001700 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001701#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001702
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001703 /* If we get here it's definitely an error */
1704
1705 (void) posix_error();
1706
1707 fail_2:
1708 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001709 PyMem_DEL(envlist[envc]);
1710 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001711 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001712 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001713 Py_XDECREF(vals);
1714 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001715 return NULL;
1716}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001717#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001718
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001719
Guido van Rossuma1065681999-01-25 23:20:23 +00001720#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001721PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001722"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001723Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001724\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001725 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001726 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001727 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001728
1729static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001730posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001731{
1732 char *path;
1733 PyObject *argv;
1734 char **argvlist;
1735 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001736 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001737 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001738
1739 /* spawnv has three arguments: (mode, path, argv), where
1740 argv is a list or tuple of strings. */
1741
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001742 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001743 return NULL;
1744 if (PyList_Check(argv)) {
1745 argc = PyList_Size(argv);
1746 getitem = PyList_GetItem;
1747 }
1748 else if (PyTuple_Check(argv)) {
1749 argc = PyTuple_Size(argv);
1750 getitem = PyTuple_GetItem;
1751 }
1752 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001753 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001754 return NULL;
1755 }
1756
1757 argvlist = PyMem_NEW(char *, argc+1);
1758 if (argvlist == NULL)
1759 return NULL;
1760 for (i = 0; i < argc; i++) {
1761 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1762 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001763 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001764 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001765 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001766 }
1767 }
1768 argvlist[argc] = NULL;
1769
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001770#if defined(PYOS_OS2) && defined(PYCC_GCC)
1771 Py_BEGIN_ALLOW_THREADS
1772 spawnval = spawnv(mode, path, argvlist);
1773 Py_END_ALLOW_THREADS
1774#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001775 if (mode == _OLD_P_OVERLAY)
1776 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001777
Tim Peters25059d32001-12-07 20:35:43 +00001778 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001779 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001780 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001781#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001782
Guido van Rossuma1065681999-01-25 23:20:23 +00001783 PyMem_DEL(argvlist);
1784
Fred Drake699f3522000-06-29 21:12:41 +00001785 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001786 return posix_error();
1787 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001788#if SIZEOF_LONG == SIZEOF_VOID_P
1789 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001790#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001791 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001792#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001793}
1794
1795
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001796PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001797"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001798Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001799\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001800 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001801 path: path of executable file\n\
1802 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001803 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001804
1805static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001806posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001807{
1808 char *path;
1809 PyObject *argv, *env;
1810 char **argvlist;
1811 char **envlist;
1812 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1813 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001814 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001815 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001816
1817 /* spawnve has four arguments: (mode, path, argv, env), where
1818 argv is a list or tuple of strings and env is a dictionary
1819 like posix.environ. */
1820
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001821 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001822 return NULL;
1823 if (PyList_Check(argv)) {
1824 argc = PyList_Size(argv);
1825 getitem = PyList_GetItem;
1826 }
1827 else if (PyTuple_Check(argv)) {
1828 argc = PyTuple_Size(argv);
1829 getitem = PyTuple_GetItem;
1830 }
1831 else {
Fred Drake661ea262000-10-24 19:57:45 +00001832 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001833 return NULL;
1834 }
1835 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001836 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001837 return NULL;
1838 }
1839
1840 argvlist = PyMem_NEW(char *, argc+1);
1841 if (argvlist == NULL) {
1842 PyErr_NoMemory();
1843 return NULL;
1844 }
1845 for (i = 0; i < argc; i++) {
1846 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001847 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001848 &argvlist[i]))
1849 {
1850 goto fail_1;
1851 }
1852 }
1853 argvlist[argc] = NULL;
1854
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001855 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001856 envlist = PyMem_NEW(char *, i + 1);
1857 if (envlist == NULL) {
1858 PyErr_NoMemory();
1859 goto fail_1;
1860 }
1861 envc = 0;
1862 keys = PyMapping_Keys(env);
1863 vals = PyMapping_Values(env);
1864 if (!keys || !vals)
1865 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001866
Guido van Rossuma1065681999-01-25 23:20:23 +00001867 for (pos = 0; pos < i; pos++) {
1868 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001869 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001870
1871 key = PyList_GetItem(keys, pos);
1872 val = PyList_GetItem(vals, pos);
1873 if (!key || !val)
1874 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001875
Fred Drake661ea262000-10-24 19:57:45 +00001876 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1877 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001878 {
1879 goto fail_2;
1880 }
Tim Petersc8996f52001-12-03 20:41:00 +00001881 len = PyString_Size(key) + PyString_Size(val) + 2;
1882 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001883 if (p == NULL) {
1884 PyErr_NoMemory();
1885 goto fail_2;
1886 }
Tim Petersc8996f52001-12-03 20:41:00 +00001887 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001888 envlist[envc++] = p;
1889 }
1890 envlist[envc] = 0;
1891
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001892#if defined(PYOS_OS2) && defined(PYCC_GCC)
1893 Py_BEGIN_ALLOW_THREADS
1894 spawnval = spawnve(mode, path, argvlist, envlist);
1895 Py_END_ALLOW_THREADS
1896#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001897 if (mode == _OLD_P_OVERLAY)
1898 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001899
1900 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001901 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001902 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001903#endif
Tim Peters25059d32001-12-07 20:35:43 +00001904
Fred Drake699f3522000-06-29 21:12:41 +00001905 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001906 (void) posix_error();
1907 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001908#if SIZEOF_LONG == SIZEOF_VOID_P
1909 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001910#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001911 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001912#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001913
1914 fail_2:
1915 while (--envc >= 0)
1916 PyMem_DEL(envlist[envc]);
1917 PyMem_DEL(envlist);
1918 fail_1:
1919 PyMem_DEL(argvlist);
1920 Py_XDECREF(vals);
1921 Py_XDECREF(keys);
1922 return res;
1923}
1924#endif /* HAVE_SPAWNV */
1925
1926
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001927#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001928PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001929"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001930Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1931\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001932Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001933
1934static PyObject *
1935posix_fork1(self, args)
1936 PyObject *self;
1937 PyObject *args;
1938{
1939 int pid;
1940 if (!PyArg_ParseTuple(args, ":fork1"))
1941 return NULL;
1942 pid = fork1();
1943 if (pid == -1)
1944 return posix_error();
1945 PyOS_AfterFork();
1946 return PyInt_FromLong((long)pid);
1947}
1948#endif
1949
1950
Guido van Rossumad0ee831995-03-01 10:34:45 +00001951#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001952PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001953"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001954Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001955Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001956
Barry Warsaw53699e91996-12-10 23:23:01 +00001957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001958posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001959{
1960 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001961 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001962 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001963 pid = fork();
1964 if (pid == -1)
1965 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001966 if (pid == 0)
1967 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001968 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001969}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001970#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001971
Fred Drake8cef4cf2000-06-28 16:40:38 +00001972#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1973#ifdef HAVE_PTY_H
1974#include <pty.h>
1975#else
1976#ifdef HAVE_LIBUTIL_H
1977#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001978#endif /* HAVE_LIBUTIL_H */
1979#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001980#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001981
Thomas Wouters70c21a12000-07-14 14:28:33 +00001982#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001983PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001984"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001985Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001986
1987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001988posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001989{
1990 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001991#ifndef HAVE_OPENPTY
1992 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001993#endif
1994
Fred Drake8cef4cf2000-06-28 16:40:38 +00001995 if (!PyArg_ParseTuple(args, ":openpty"))
1996 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001997
1998#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00001999 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2000 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00002001#else
2002 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2003 if (slave_name == NULL)
2004 return posix_error();
2005
2006 slave_fd = open(slave_name, O_RDWR);
2007 if (slave_fd < 0)
2008 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002009#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002010
Fred Drake8cef4cf2000-06-28 16:40:38 +00002011 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002012
Fred Drake8cef4cf2000-06-28 16:40:38 +00002013}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002014#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002015
2016#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002017PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002018"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002019Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2020Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002021To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002022
2023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002024posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002025{
2026 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002027
Fred Drake8cef4cf2000-06-28 16:40:38 +00002028 if (!PyArg_ParseTuple(args, ":forkpty"))
2029 return NULL;
2030 pid = forkpty(&master_fd, NULL, NULL, NULL);
2031 if (pid == -1)
2032 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002033 if (pid == 0)
2034 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002035 return Py_BuildValue("(ii)", pid, master_fd);
2036}
2037#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002038
Guido van Rossumad0ee831995-03-01 10:34:45 +00002039#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002040PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002041"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002042Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002043
Barry Warsaw53699e91996-12-10 23:23:01 +00002044static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002045posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002046{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002047 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002048 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002049 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002050}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002051#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002053
Guido van Rossumad0ee831995-03-01 10:34:45 +00002054#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002055PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002056"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002057Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002058
Barry Warsaw53699e91996-12-10 23:23:01 +00002059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002060posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002061{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002062 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002063 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002064 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002065}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002066#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068
Guido van Rossumad0ee831995-03-01 10:34:45 +00002069#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002070PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002071"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002072Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002073
Barry Warsaw53699e91996-12-10 23:23:01 +00002074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002075posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002076{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002077 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002078 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002079 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002080}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002081#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002083
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002084PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002085"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002086Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087
Barry Warsaw53699e91996-12-10 23:23:01 +00002088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002089posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002090{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002091 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002092 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002093 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002094}
2095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002096
Fred Drakec9680921999-12-13 16:37:25 +00002097#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002098PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002099"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002100Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002101
2102static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002103posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002104{
2105 PyObject *result = NULL;
2106
2107 if (PyArg_ParseTuple(args, ":getgroups")) {
2108#ifdef NGROUPS_MAX
2109#define MAX_GROUPS NGROUPS_MAX
2110#else
2111 /* defined to be 16 on Solaris7, so this should be a small number */
2112#define MAX_GROUPS 64
2113#endif
2114 gid_t grouplist[MAX_GROUPS];
2115 int n;
2116
2117 n = getgroups(MAX_GROUPS, grouplist);
2118 if (n < 0)
2119 posix_error();
2120 else {
2121 result = PyList_New(n);
2122 if (result != NULL) {
2123 PyObject *o;
2124 int i;
2125 for (i = 0; i < n; ++i) {
2126 o = PyInt_FromLong((long)grouplist[i]);
2127 if (o == NULL) {
2128 Py_DECREF(result);
2129 result = NULL;
2130 break;
2131 }
2132 PyList_SET_ITEM(result, i, o);
2133 }
2134 }
2135 }
2136 }
2137 return result;
2138}
2139#endif
2140
Martin v. Löwis606edc12002-06-13 21:09:11 +00002141#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002142PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002143"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002144Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002145
2146static PyObject *
2147posix_getpgid(PyObject *self, PyObject *args)
2148{
2149 int pid, pgid;
2150 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2151 return NULL;
2152 pgid = getpgid(pid);
2153 if (pgid < 0)
2154 return posix_error();
2155 return PyInt_FromLong((long)pgid);
2156}
2157#endif /* HAVE_GETPGID */
2158
2159
Guido van Rossumb6775db1994-08-01 11:34:53 +00002160#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002161PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002162"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002163Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002164
Barry Warsaw53699e91996-12-10 23:23:01 +00002165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002166posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002167{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002168 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002169 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002170#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002171 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002172#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002173 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002174#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002175}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002176#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002177
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002178
Guido van Rossumb6775db1994-08-01 11:34:53 +00002179#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002180PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002181"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002182Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002183
Barry Warsaw53699e91996-12-10 23:23:01 +00002184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002185posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002186{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002187 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002188 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002189#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002190 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002191#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002192 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002193#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002194 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002195 Py_INCREF(Py_None);
2196 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002197}
2198
Guido van Rossumb6775db1994-08-01 11:34:53 +00002199#endif /* HAVE_SETPGRP */
2200
Guido van Rossumad0ee831995-03-01 10:34:45 +00002201#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002202PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002203"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002204Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002205
Barry Warsaw53699e91996-12-10 23:23:01 +00002206static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002207posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002208{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002209 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002210 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002211 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002212}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002213#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002214
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002215
Fred Drake12c6e2d1999-12-14 21:25:03 +00002216#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002217PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002218"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002219Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002220
2221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002222posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002223{
2224 PyObject *result = NULL;
2225
2226 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002227 char *name;
2228 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002229
Fred Drakea30680b2000-12-06 21:24:28 +00002230 errno = 0;
2231 name = getlogin();
2232 if (name == NULL) {
2233 if (errno)
2234 posix_error();
2235 else
2236 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002237 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002238 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002239 else
2240 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002241 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002242 }
2243 return result;
2244}
2245#endif
2246
Guido van Rossumad0ee831995-03-01 10:34:45 +00002247#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002248PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002249"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002250Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002251
Barry Warsaw53699e91996-12-10 23:23:01 +00002252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002253posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002254{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002255 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002256 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002257 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002258}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002259#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002260
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002261
Guido van Rossumad0ee831995-03-01 10:34:45 +00002262#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002263PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002264"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002265Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002266
Barry Warsaw53699e91996-12-10 23:23:01 +00002267static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002268posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002269{
2270 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002271 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002272 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002273#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002274 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2275 APIRET rc;
2276 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002277 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002278
2279 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2280 APIRET rc;
2281 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002282 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002283
2284 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002285 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002286#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002287 if (kill(pid, sig) == -1)
2288 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002289#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002290 Py_INCREF(Py_None);
2291 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002292}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002293#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002294
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002295#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002296PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002297"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002298Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002299
2300static PyObject *
2301posix_killpg(PyObject *self, PyObject *args)
2302{
2303 int pgid, sig;
2304 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2305 return NULL;
2306 if (killpg(pgid, sig) == -1)
2307 return posix_error();
2308 Py_INCREF(Py_None);
2309 return Py_None;
2310}
2311#endif
2312
Guido van Rossumc0125471996-06-28 18:55:32 +00002313#ifdef HAVE_PLOCK
2314
2315#ifdef HAVE_SYS_LOCK_H
2316#include <sys/lock.h>
2317#endif
2318
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002319PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002320"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002321Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002322
Barry Warsaw53699e91996-12-10 23:23:01 +00002323static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002324posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002325{
2326 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002327 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002328 return NULL;
2329 if (plock(op) == -1)
2330 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002331 Py_INCREF(Py_None);
2332 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002333}
2334#endif
2335
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002336
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002337#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002338PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002339"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002340Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002341
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002342#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002343#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002344static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002345async_system(const char *command)
2346{
2347 char *p, errormsg[256], args[1024];
2348 RESULTCODES rcodes;
2349 APIRET rc;
2350 char *shell = getenv("COMSPEC");
2351 if (!shell)
2352 shell = "cmd";
2353
2354 strcpy(args, shell);
2355 p = &args[ strlen(args)+1 ];
2356 strcpy(p, "/c ");
2357 strcat(p, command);
2358 p += strlen(p) + 1;
2359 *p = '\0';
2360
2361 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002362 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002363 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002364 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002365 &rcodes, shell);
2366 return rc;
2367}
2368
Guido van Rossumd48f2521997-12-05 22:19:34 +00002369static FILE *
2370popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002371{
2372 HFILE rhan, whan;
2373 FILE *retfd = NULL;
2374 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2375
Guido van Rossumd48f2521997-12-05 22:19:34 +00002376 if (rc != NO_ERROR) {
2377 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002378 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002379 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002380
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002381 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2382 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002383
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002384 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2385 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002386
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002387 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2388 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002389
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002390 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002391 }
2392
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002393 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2394 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002395
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002396 if (rc == NO_ERROR)
2397 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2398
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002399 close(oldfd); /* And Close Saved STDOUT Handle */
2400 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002401
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002402 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2403 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002404
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002405 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2406 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002407
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002408 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2409 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002410
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002411 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002412 }
2413
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002414 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2415 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002416
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002417 if (rc == NO_ERROR)
2418 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2419
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002420 close(oldfd); /* And Close Saved STDIN Handle */
2421 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002422
Guido van Rossumd48f2521997-12-05 22:19:34 +00002423 } else {
2424 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002425 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002426 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002427}
2428
2429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002430posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002431{
2432 char *name;
2433 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002434 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002435 FILE *fp;
2436 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002437 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002438 return NULL;
2439 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002440 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002441 Py_END_ALLOW_THREADS
2442 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002443 return os2_error(err);
2444
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002445 f = PyFile_FromFile(fp, name, mode, fclose);
2446 if (f != NULL)
2447 PyFile_SetBufSize(f, bufsize);
2448 return f;
2449}
2450
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002451#elif defined(PYCC_GCC)
2452
2453/* standard posix version of popen() support */
2454static PyObject *
2455posix_popen(PyObject *self, PyObject *args)
2456{
2457 char *name;
2458 char *mode = "r";
2459 int bufsize = -1;
2460 FILE *fp;
2461 PyObject *f;
2462 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2463 return NULL;
2464 Py_BEGIN_ALLOW_THREADS
2465 fp = popen(name, mode);
2466 Py_END_ALLOW_THREADS
2467 if (fp == NULL)
2468 return posix_error();
2469 f = PyFile_FromFile(fp, name, mode, pclose);
2470 if (f != NULL)
2471 PyFile_SetBufSize(f, bufsize);
2472 return f;
2473}
2474
2475/* fork() under OS/2 has lots'o'warts
2476 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2477 * most of this code is a ripoff of the win32 code, but using the
2478 * capabilities of EMX's C library routines
2479 */
2480
2481/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2482#define POPEN_1 1
2483#define POPEN_2 2
2484#define POPEN_3 3
2485#define POPEN_4 4
2486
2487static PyObject *_PyPopen(char *, int, int, int);
2488static int _PyPclose(FILE *file);
2489
2490/*
2491 * Internal dictionary mapping popen* file pointers to process handles,
2492 * for use when retrieving the process exit code. See _PyPclose() below
2493 * for more information on this dictionary's use.
2494 */
2495static PyObject *_PyPopenProcs = NULL;
2496
2497/* os2emx version of popen2()
2498 *
2499 * The result of this function is a pipe (file) connected to the
2500 * process's stdin, and a pipe connected to the process's stdout.
2501 */
2502
2503static PyObject *
2504os2emx_popen2(PyObject *self, PyObject *args)
2505{
2506 PyObject *f;
2507 int tm=0;
2508
2509 char *cmdstring;
2510 char *mode = "t";
2511 int bufsize = -1;
2512 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2513 return NULL;
2514
2515 if (*mode == 't')
2516 tm = O_TEXT;
2517 else if (*mode != 'b') {
2518 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2519 return NULL;
2520 } else
2521 tm = O_BINARY;
2522
2523 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2524
2525 return f;
2526}
2527
2528/*
2529 * Variation on os2emx.popen2
2530 *
2531 * The result of this function is 3 pipes - the process's stdin,
2532 * stdout and stderr
2533 */
2534
2535static PyObject *
2536os2emx_popen3(PyObject *self, PyObject *args)
2537{
2538 PyObject *f;
2539 int tm = 0;
2540
2541 char *cmdstring;
2542 char *mode = "t";
2543 int bufsize = -1;
2544 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2545 return NULL;
2546
2547 if (*mode == 't')
2548 tm = O_TEXT;
2549 else if (*mode != 'b') {
2550 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2551 return NULL;
2552 } else
2553 tm = O_BINARY;
2554
2555 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2556
2557 return f;
2558}
2559
2560/*
2561 * Variation on os2emx.popen2
2562 *
2563 * The result of this function is 2 pipes - the processes stdin,
2564 * and stdout+stderr combined as a single pipe.
2565 */
2566
2567static PyObject *
2568os2emx_popen4(PyObject *self, PyObject *args)
2569{
2570 PyObject *f;
2571 int tm = 0;
2572
2573 char *cmdstring;
2574 char *mode = "t";
2575 int bufsize = -1;
2576 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2577 return NULL;
2578
2579 if (*mode == 't')
2580 tm = O_TEXT;
2581 else if (*mode != 'b') {
2582 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2583 return NULL;
2584 } else
2585 tm = O_BINARY;
2586
2587 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2588
2589 return f;
2590}
2591
2592/* a couple of structures for convenient handling of multiple
2593 * file handles and pipes
2594 */
2595struct file_ref
2596{
2597 int handle;
2598 int flags;
2599};
2600
2601struct pipe_ref
2602{
2603 int rd;
2604 int wr;
2605};
2606
2607/* The following code is derived from the win32 code */
2608
2609static PyObject *
2610_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2611{
2612 struct file_ref stdio[3];
2613 struct pipe_ref p_fd[3];
2614 FILE *p_s[3];
2615 int file_count, i, pipe_err, pipe_pid;
2616 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2617 PyObject *f, *p_f[3];
2618
2619 /* file modes for subsequent fdopen's on pipe handles */
2620 if (mode == O_TEXT)
2621 {
2622 rd_mode = "rt";
2623 wr_mode = "wt";
2624 }
2625 else
2626 {
2627 rd_mode = "rb";
2628 wr_mode = "wb";
2629 }
2630
2631 /* prepare shell references */
2632 if ((shell = getenv("EMXSHELL")) == NULL)
2633 if ((shell = getenv("COMSPEC")) == NULL)
2634 {
2635 errno = ENOENT;
2636 return posix_error();
2637 }
2638
2639 sh_name = _getname(shell);
2640 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2641 opt = "/c";
2642 else
2643 opt = "-c";
2644
2645 /* save current stdio fds + their flags, and set not inheritable */
2646 i = pipe_err = 0;
2647 while (pipe_err >= 0 && i < 3)
2648 {
2649 pipe_err = stdio[i].handle = dup(i);
2650 stdio[i].flags = fcntl(i, F_GETFD, 0);
2651 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2652 i++;
2653 }
2654 if (pipe_err < 0)
2655 {
2656 /* didn't get them all saved - clean up and bail out */
2657 int saved_err = errno;
2658 while (i-- > 0)
2659 {
2660 close(stdio[i].handle);
2661 }
2662 errno = saved_err;
2663 return posix_error();
2664 }
2665
2666 /* create pipe ends */
2667 file_count = 2;
2668 if (n == POPEN_3)
2669 file_count = 3;
2670 i = pipe_err = 0;
2671 while ((pipe_err == 0) && (i < file_count))
2672 pipe_err = pipe((int *)&p_fd[i++]);
2673 if (pipe_err < 0)
2674 {
2675 /* didn't get them all made - clean up and bail out */
2676 while (i-- > 0)
2677 {
2678 close(p_fd[i].wr);
2679 close(p_fd[i].rd);
2680 }
2681 errno = EPIPE;
2682 return posix_error();
2683 }
2684
2685 /* change the actual standard IO streams over temporarily,
2686 * making the retained pipe ends non-inheritable
2687 */
2688 pipe_err = 0;
2689
2690 /* - stdin */
2691 if (dup2(p_fd[0].rd, 0) == 0)
2692 {
2693 close(p_fd[0].rd);
2694 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2695 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2696 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2697 {
2698 close(p_fd[0].wr);
2699 pipe_err = -1;
2700 }
2701 }
2702 else
2703 {
2704 pipe_err = -1;
2705 }
2706
2707 /* - stdout */
2708 if (pipe_err == 0)
2709 {
2710 if (dup2(p_fd[1].wr, 1) == 1)
2711 {
2712 close(p_fd[1].wr);
2713 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2714 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2715 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2716 {
2717 close(p_fd[1].rd);
2718 pipe_err = -1;
2719 }
2720 }
2721 else
2722 {
2723 pipe_err = -1;
2724 }
2725 }
2726
2727 /* - stderr, as required */
2728 if (pipe_err == 0)
2729 switch (n)
2730 {
2731 case POPEN_3:
2732 {
2733 if (dup2(p_fd[2].wr, 2) == 2)
2734 {
2735 close(p_fd[2].wr);
2736 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2737 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2738 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2739 {
2740 close(p_fd[2].rd);
2741 pipe_err = -1;
2742 }
2743 }
2744 else
2745 {
2746 pipe_err = -1;
2747 }
2748 break;
2749 }
2750
2751 case POPEN_4:
2752 {
2753 if (dup2(1, 2) != 2)
2754 {
2755 pipe_err = -1;
2756 }
2757 break;
2758 }
2759 }
2760
2761 /* spawn the child process */
2762 if (pipe_err == 0)
2763 {
2764 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2765 if (pipe_pid == -1)
2766 {
2767 pipe_err = -1;
2768 }
2769 else
2770 {
2771 /* save the PID into the FILE structure
2772 * NOTE: this implementation doesn't actually
2773 * take advantage of this, but do it for
2774 * completeness - AIM Apr01
2775 */
2776 for (i = 0; i < file_count; i++)
2777 p_s[i]->_pid = pipe_pid;
2778 }
2779 }
2780
2781 /* reset standard IO to normal */
2782 for (i = 0; i < 3; i++)
2783 {
2784 dup2(stdio[i].handle, i);
2785 fcntl(i, F_SETFD, stdio[i].flags);
2786 close(stdio[i].handle);
2787 }
2788
2789 /* if any remnant problems, clean up and bail out */
2790 if (pipe_err < 0)
2791 {
2792 for (i = 0; i < 3; i++)
2793 {
2794 close(p_fd[i].rd);
2795 close(p_fd[i].wr);
2796 }
2797 errno = EPIPE;
2798 return posix_error_with_filename(cmdstring);
2799 }
2800
2801 /* build tuple of file objects to return */
2802 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2803 PyFile_SetBufSize(p_f[0], bufsize);
2804 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2805 PyFile_SetBufSize(p_f[1], bufsize);
2806 if (n == POPEN_3)
2807 {
2808 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2809 PyFile_SetBufSize(p_f[0], bufsize);
2810 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2811 }
2812 else
2813 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2814
2815 /*
2816 * Insert the files we've created into the process dictionary
2817 * all referencing the list with the process handle and the
2818 * initial number of files (see description below in _PyPclose).
2819 * Since if _PyPclose later tried to wait on a process when all
2820 * handles weren't closed, it could create a deadlock with the
2821 * child, we spend some energy here to try to ensure that we
2822 * either insert all file handles into the dictionary or none
2823 * at all. It's a little clumsy with the various popen modes
2824 * and variable number of files involved.
2825 */
2826 if (!_PyPopenProcs)
2827 {
2828 _PyPopenProcs = PyDict_New();
2829 }
2830
2831 if (_PyPopenProcs)
2832 {
2833 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2834 int ins_rc[3];
2835
2836 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2837 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2838
2839 procObj = PyList_New(2);
2840 pidObj = PyInt_FromLong((long) pipe_pid);
2841 intObj = PyInt_FromLong((long) file_count);
2842
2843 if (procObj && pidObj && intObj)
2844 {
2845 PyList_SetItem(procObj, 0, pidObj);
2846 PyList_SetItem(procObj, 1, intObj);
2847
2848 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2849 if (fileObj[0])
2850 {
2851 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2852 fileObj[0],
2853 procObj);
2854 }
2855 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2856 if (fileObj[1])
2857 {
2858 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2859 fileObj[1],
2860 procObj);
2861 }
2862 if (file_count >= 3)
2863 {
2864 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2865 if (fileObj[2])
2866 {
2867 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2868 fileObj[2],
2869 procObj);
2870 }
2871 }
2872
2873 if (ins_rc[0] < 0 || !fileObj[0] ||
2874 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2875 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2876 {
2877 /* Something failed - remove any dictionary
2878 * entries that did make it.
2879 */
2880 if (!ins_rc[0] && fileObj[0])
2881 {
2882 PyDict_DelItem(_PyPopenProcs,
2883 fileObj[0]);
2884 }
2885 if (!ins_rc[1] && fileObj[1])
2886 {
2887 PyDict_DelItem(_PyPopenProcs,
2888 fileObj[1]);
2889 }
2890 if (!ins_rc[2] && fileObj[2])
2891 {
2892 PyDict_DelItem(_PyPopenProcs,
2893 fileObj[2]);
2894 }
2895 }
2896 }
2897
2898 /*
2899 * Clean up our localized references for the dictionary keys
2900 * and value since PyDict_SetItem will Py_INCREF any copies
2901 * that got placed in the dictionary.
2902 */
2903 Py_XDECREF(procObj);
2904 Py_XDECREF(fileObj[0]);
2905 Py_XDECREF(fileObj[1]);
2906 Py_XDECREF(fileObj[2]);
2907 }
2908
2909 /* Child is launched. */
2910 return f;
2911}
2912
2913/*
2914 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2915 * exit code for the child process and return as a result of the close.
2916 *
2917 * This function uses the _PyPopenProcs dictionary in order to map the
2918 * input file pointer to information about the process that was
2919 * originally created by the popen* call that created the file pointer.
2920 * The dictionary uses the file pointer as a key (with one entry
2921 * inserted for each file returned by the original popen* call) and a
2922 * single list object as the value for all files from a single call.
2923 * The list object contains the Win32 process handle at [0], and a file
2924 * count at [1], which is initialized to the total number of file
2925 * handles using that list.
2926 *
2927 * This function closes whichever handle it is passed, and decrements
2928 * the file count in the dictionary for the process handle pointed to
2929 * by this file. On the last close (when the file count reaches zero),
2930 * this function will wait for the child process and then return its
2931 * exit code as the result of the close() operation. This permits the
2932 * files to be closed in any order - it is always the close() of the
2933 * final handle that will return the exit code.
2934 */
2935
2936 /* RED_FLAG 31-Aug-2000 Tim
2937 * This is always called (today!) between a pair of
2938 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2939 * macros. So the thread running this has no valid thread state, as
2940 * far as Python is concerned. However, this calls some Python API
2941 * functions that cannot be called safely without a valid thread
2942 * state, in particular PyDict_GetItem.
2943 * As a temporary hack (although it may last for years ...), we
2944 * *rely* on not having a valid thread state in this function, in
2945 * order to create our own "from scratch".
2946 * This will deadlock if _PyPclose is ever called by a thread
2947 * holding the global lock.
2948 * (The OS/2 EMX thread support appears to cover the case where the
2949 * lock is already held - AIM Apr01)
2950 */
2951
2952static int _PyPclose(FILE *file)
2953{
2954 int result;
2955 int exit_code;
2956 int pipe_pid;
2957 PyObject *procObj, *pidObj, *intObj, *fileObj;
2958 int file_count;
2959#ifdef WITH_THREAD
2960 PyInterpreterState* pInterpreterState;
2961 PyThreadState* pThreadState;
2962#endif
2963
2964 /* Close the file handle first, to ensure it can't block the
2965 * child from exiting if it's the last handle.
2966 */
2967 result = fclose(file);
2968
2969#ifdef WITH_THREAD
2970 /* Bootstrap a valid thread state into existence. */
2971 pInterpreterState = PyInterpreterState_New();
2972 if (!pInterpreterState) {
2973 /* Well, we're hosed now! We don't have a thread
2974 * state, so can't call a nice error routine, or raise
2975 * an exception. Just die.
2976 */
2977 Py_FatalError("unable to allocate interpreter state "
2978 "when closing popen object.");
2979 return -1; /* unreachable */
2980 }
2981 pThreadState = PyThreadState_New(pInterpreterState);
2982 if (!pThreadState) {
2983 Py_FatalError("unable to allocate thread state "
2984 "when closing popen object.");
2985 return -1; /* unreachable */
2986 }
2987 /* Grab the global lock. Note that this will deadlock if the
2988 * current thread already has the lock! (see RED_FLAG comments
2989 * before this function)
2990 */
2991 PyEval_RestoreThread(pThreadState);
2992#endif
2993
2994 if (_PyPopenProcs)
2995 {
2996 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
2997 (procObj = PyDict_GetItem(_PyPopenProcs,
2998 fileObj)) != NULL &&
2999 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3000 (intObj = PyList_GetItem(procObj,1)) != NULL)
3001 {
3002 pipe_pid = (int) PyInt_AsLong(pidObj);
3003 file_count = (int) PyInt_AsLong(intObj);
3004
3005 if (file_count > 1)
3006 {
3007 /* Still other files referencing process */
3008 file_count--;
3009 PyList_SetItem(procObj,1,
3010 PyInt_FromLong((long) file_count));
3011 }
3012 else
3013 {
3014 /* Last file for this process */
3015 if (result != EOF &&
3016 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3017 {
3018 /* extract exit status */
3019 if (WIFEXITED(exit_code))
3020 {
3021 result = WEXITSTATUS(exit_code);
3022 }
3023 else
3024 {
3025 errno = EPIPE;
3026 result = -1;
3027 }
3028 }
3029 else
3030 {
3031 /* Indicate failure - this will cause the file object
3032 * to raise an I/O error and translate the last
3033 * error code from errno. We do have a problem with
3034 * last errors that overlap the normal errno table,
3035 * but that's a consistent problem with the file object.
3036 */
3037 result = -1;
3038 }
3039 }
3040
3041 /* Remove this file pointer from dictionary */
3042 PyDict_DelItem(_PyPopenProcs, fileObj);
3043
3044 if (PyDict_Size(_PyPopenProcs) == 0)
3045 {
3046 Py_DECREF(_PyPopenProcs);
3047 _PyPopenProcs = NULL;
3048 }
3049
3050 } /* if object retrieval ok */
3051
3052 Py_XDECREF(fileObj);
3053 } /* if _PyPopenProcs */
3054
3055#ifdef WITH_THREAD
3056 /* Tear down the thread & interpreter states.
3057 * Note that interpreter state clear & delete functions automatically
3058 * call the thread clear & delete functions, and indeed insist on
3059 * doing that themselves. The lock must be held during the clear, but
3060 * need not be held during the delete.
3061 */
3062 PyInterpreterState_Clear(pInterpreterState);
3063 PyEval_ReleaseThread(pThreadState);
3064 PyInterpreterState_Delete(pInterpreterState);
3065#endif
3066
3067 return result;
3068}
3069
3070#endif /* PYCC_??? */
3071
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003072#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003073
3074/*
3075 * Portable 'popen' replacement for Win32.
3076 *
3077 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3078 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003079 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003080 */
3081
3082#include <malloc.h>
3083#include <io.h>
3084#include <fcntl.h>
3085
3086/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3087#define POPEN_1 1
3088#define POPEN_2 2
3089#define POPEN_3 3
3090#define POPEN_4 4
3091
3092static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003093static int _PyPclose(FILE *file);
3094
3095/*
3096 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003097 * for use when retrieving the process exit code. See _PyPclose() below
3098 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003099 */
3100static PyObject *_PyPopenProcs = NULL;
3101
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003102
3103/* popen that works from a GUI.
3104 *
3105 * The result of this function is a pipe (file) connected to the
3106 * processes stdin or stdout, depending on the requested mode.
3107 */
3108
3109static PyObject *
3110posix_popen(PyObject *self, PyObject *args)
3111{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003112 PyObject *f, *s;
3113 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003114
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003115 char *cmdstring;
3116 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003117 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003118 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003119 return NULL;
3120
3121 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003122
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003123 if (*mode == 'r')
3124 tm = _O_RDONLY;
3125 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003126 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003127 return NULL;
3128 } else
3129 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003130
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003131 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003132 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003133 return NULL;
3134 }
3135
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003136 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003137 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003138 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003139 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003140 else
3141 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3142
3143 return f;
3144}
3145
3146/* Variation on win32pipe.popen
3147 *
3148 * The result of this function is a pipe (file) connected to the
3149 * process's stdin, and a pipe connected to the process's stdout.
3150 */
3151
3152static PyObject *
3153win32_popen2(PyObject *self, PyObject *args)
3154{
3155 PyObject *f;
3156 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003157
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003158 char *cmdstring;
3159 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003160 int bufsize = -1;
3161 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003162 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003163
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003164 if (*mode == 't')
3165 tm = _O_TEXT;
3166 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003167 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003168 return NULL;
3169 } else
3170 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003171
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003172 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003173 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003174 return NULL;
3175 }
3176
3177 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003178
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003179 return f;
3180}
3181
3182/*
3183 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003184 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003185 * The result of this function is 3 pipes - the process's stdin,
3186 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003187 */
3188
3189static PyObject *
3190win32_popen3(PyObject *self, PyObject *args)
3191{
3192 PyObject *f;
3193 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003194
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003195 char *cmdstring;
3196 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003197 int bufsize = -1;
3198 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003199 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003200
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003201 if (*mode == 't')
3202 tm = _O_TEXT;
3203 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003204 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003205 return NULL;
3206 } else
3207 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003208
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003209 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003210 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003211 return NULL;
3212 }
3213
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003214 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003215
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003216 return f;
3217}
3218
3219/*
3220 * Variation on win32pipe.popen
3221 *
Tim Peters5aa91602002-01-30 05:46:57 +00003222 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003223 * and stdout+stderr combined as a single pipe.
3224 */
3225
3226static PyObject *
3227win32_popen4(PyObject *self, PyObject *args)
3228{
3229 PyObject *f;
3230 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003231
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003232 char *cmdstring;
3233 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003234 int bufsize = -1;
3235 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003236 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003237
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003238 if (*mode == 't')
3239 tm = _O_TEXT;
3240 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003241 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003242 return NULL;
3243 } else
3244 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003245
3246 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003247 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003248 return NULL;
3249 }
3250
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003251 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003252
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003253 return f;
3254}
3255
Mark Hammond08501372001-01-31 07:30:29 +00003256static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003257_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003258 HANDLE hStdin,
3259 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003260 HANDLE hStderr,
3261 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003262{
3263 PROCESS_INFORMATION piProcInfo;
3264 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003265 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003266 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003267 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003268 int i;
3269 int x;
3270
3271 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003272 char *comshell;
3273
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003274 s1 = (char *)_alloca(i);
3275 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3276 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003277
3278 /* Explicitly check if we are using COMMAND.COM. If we are
3279 * then use the w9xpopen hack.
3280 */
3281 comshell = s1 + x;
3282 while (comshell >= s1 && *comshell != '\\')
3283 --comshell;
3284 ++comshell;
3285
3286 if (GetVersion() < 0x80000000 &&
3287 _stricmp(comshell, "command.com") != 0) {
3288 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003289 x = i + strlen(s3) + strlen(cmdstring) + 1;
3290 s2 = (char *)_alloca(x);
3291 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003292 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003293 }
3294 else {
3295 /*
Tim Peters402d5982001-08-27 06:37:48 +00003296 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3297 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003298 */
Mark Hammond08501372001-01-31 07:30:29 +00003299 char modulepath[_MAX_PATH];
3300 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003301 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3302 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003303 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003304 x = i+1;
3305 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003306 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003307 strncat(modulepath,
3308 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003309 (sizeof(modulepath)/sizeof(modulepath[0]))
3310 -strlen(modulepath));
3311 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003312 /* Eeek - file-not-found - possibly an embedding
3313 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003314 */
Tim Peters5aa91602002-01-30 05:46:57 +00003315 strncpy(modulepath,
3316 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003317 sizeof(modulepath)/sizeof(modulepath[0]));
3318 if (modulepath[strlen(modulepath)-1] != '\\')
3319 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003320 strncat(modulepath,
3321 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003322 (sizeof(modulepath)/sizeof(modulepath[0]))
3323 -strlen(modulepath));
3324 /* No where else to look - raise an easily identifiable
3325 error, rather than leaving Windows to report
3326 "file not found" - as the user is probably blissfully
3327 unaware this shim EXE is used, and it will confuse them.
3328 (well, it confused me for a while ;-)
3329 */
3330 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003331 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003332 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003333 "for popen to work with your shell "
3334 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003335 szConsoleSpawn);
3336 return FALSE;
3337 }
3338 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003339 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003340 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003341 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003342
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003343 s2 = (char *)_alloca(x);
3344 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003345 /* To maintain correct argument passing semantics,
3346 we pass the command-line as it stands, and allow
3347 quoting to be applied. w9xpopen.exe will then
3348 use its argv vector, and re-quote the necessary
3349 args for the ultimate child process.
3350 */
Tim Peters75cdad52001-11-28 22:07:30 +00003351 PyOS_snprintf(
3352 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003353 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003354 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003355 s1,
3356 s3,
3357 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003358 /* Not passing CREATE_NEW_CONSOLE has been known to
3359 cause random failures on win9x. Specifically a
3360 dialog:
3361 "Your program accessed mem currently in use at xxx"
3362 and a hopeful warning about the stability of your
3363 system.
3364 Cost is Ctrl+C wont kill children, but anyone
3365 who cares can have a go!
3366 */
3367 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003368 }
3369 }
3370
3371 /* Could be an else here to try cmd.exe / command.com in the path
3372 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003373 else {
Tim Peters402d5982001-08-27 06:37:48 +00003374 PyErr_SetString(PyExc_RuntimeError,
3375 "Cannot locate a COMSPEC environment variable to "
3376 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003377 return FALSE;
3378 }
Tim Peters5aa91602002-01-30 05:46:57 +00003379
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003380 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3381 siStartInfo.cb = sizeof(STARTUPINFO);
3382 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3383 siStartInfo.hStdInput = hStdin;
3384 siStartInfo.hStdOutput = hStdout;
3385 siStartInfo.hStdError = hStderr;
3386 siStartInfo.wShowWindow = SW_HIDE;
3387
3388 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003389 s2,
3390 NULL,
3391 NULL,
3392 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003393 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003394 NULL,
3395 NULL,
3396 &siStartInfo,
3397 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003398 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003399 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003400
Mark Hammondb37a3732000-08-14 04:47:33 +00003401 /* Return process handle */
3402 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003403 return TRUE;
3404 }
Tim Peters402d5982001-08-27 06:37:48 +00003405 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003406 return FALSE;
3407}
3408
3409/* The following code is based off of KB: Q190351 */
3410
3411static PyObject *
3412_PyPopen(char *cmdstring, int mode, int n)
3413{
3414 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3415 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003416 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003417
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003418 SECURITY_ATTRIBUTES saAttr;
3419 BOOL fSuccess;
3420 int fd1, fd2, fd3;
3421 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003422 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003423 PyObject *f;
3424
3425 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3426 saAttr.bInheritHandle = TRUE;
3427 saAttr.lpSecurityDescriptor = NULL;
3428
3429 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3430 return win32_error("CreatePipe", NULL);
3431
3432 /* Create new output read handle and the input write handle. Set
3433 * the inheritance properties to FALSE. Otherwise, the child inherits
3434 * the these handles; resulting in non-closeable handles to the pipes
3435 * being created. */
3436 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003437 GetCurrentProcess(), &hChildStdinWrDup, 0,
3438 FALSE,
3439 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003440 if (!fSuccess)
3441 return win32_error("DuplicateHandle", NULL);
3442
3443 /* Close the inheritable version of ChildStdin
3444 that we're using. */
3445 CloseHandle(hChildStdinWr);
3446
3447 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3448 return win32_error("CreatePipe", NULL);
3449
3450 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003451 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3452 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003453 if (!fSuccess)
3454 return win32_error("DuplicateHandle", NULL);
3455
3456 /* Close the inheritable version of ChildStdout
3457 that we're using. */
3458 CloseHandle(hChildStdoutRd);
3459
3460 if (n != POPEN_4) {
3461 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3462 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003463 fSuccess = DuplicateHandle(GetCurrentProcess(),
3464 hChildStderrRd,
3465 GetCurrentProcess(),
3466 &hChildStderrRdDup, 0,
3467 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003468 if (!fSuccess)
3469 return win32_error("DuplicateHandle", NULL);
3470 /* Close the inheritable version of ChildStdErr that we're using. */
3471 CloseHandle(hChildStderrRd);
3472 }
Tim Peters5aa91602002-01-30 05:46:57 +00003473
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003474 switch (n) {
3475 case POPEN_1:
3476 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3477 case _O_WRONLY | _O_TEXT:
3478 /* Case for writing to child Stdin in text mode. */
3479 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3480 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003481 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003482 PyFile_SetBufSize(f, 0);
3483 /* We don't care about these pipes anymore, so close them. */
3484 CloseHandle(hChildStdoutRdDup);
3485 CloseHandle(hChildStderrRdDup);
3486 break;
3487
3488 case _O_RDONLY | _O_TEXT:
3489 /* Case for reading from child Stdout in text mode. */
3490 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3491 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003492 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003493 PyFile_SetBufSize(f, 0);
3494 /* We don't care about these pipes anymore, so close them. */
3495 CloseHandle(hChildStdinWrDup);
3496 CloseHandle(hChildStderrRdDup);
3497 break;
3498
3499 case _O_RDONLY | _O_BINARY:
3500 /* Case for readinig from child Stdout in binary mode. */
3501 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3502 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003503 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003504 PyFile_SetBufSize(f, 0);
3505 /* We don't care about these pipes anymore, so close them. */
3506 CloseHandle(hChildStdinWrDup);
3507 CloseHandle(hChildStderrRdDup);
3508 break;
3509
3510 case _O_WRONLY | _O_BINARY:
3511 /* Case for writing to child Stdin in binary mode. */
3512 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3513 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003514 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003515 PyFile_SetBufSize(f, 0);
3516 /* We don't care about these pipes anymore, so close them. */
3517 CloseHandle(hChildStdoutRdDup);
3518 CloseHandle(hChildStderrRdDup);
3519 break;
3520 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003521 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003522 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003523
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003524 case POPEN_2:
3525 case POPEN_4:
3526 {
3527 char *m1, *m2;
3528 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003529
Tim Peters7dca21e2002-08-19 00:42:29 +00003530 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003531 m1 = "r";
3532 m2 = "w";
3533 } else {
3534 m1 = "rb";
3535 m2 = "wb";
3536 }
3537
3538 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3539 f1 = _fdopen(fd1, m2);
3540 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3541 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003542 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003543 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003544 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003545 PyFile_SetBufSize(p2, 0);
3546
3547 if (n != 4)
3548 CloseHandle(hChildStderrRdDup);
3549
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003550 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003551 Py_XDECREF(p1);
3552 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003553 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003554 break;
3555 }
Tim Peters5aa91602002-01-30 05:46:57 +00003556
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003557 case POPEN_3:
3558 {
3559 char *m1, *m2;
3560 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003561
Tim Peters7dca21e2002-08-19 00:42:29 +00003562 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003563 m1 = "r";
3564 m2 = "w";
3565 } else {
3566 m1 = "rb";
3567 m2 = "wb";
3568 }
3569
3570 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3571 f1 = _fdopen(fd1, m2);
3572 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3573 f2 = _fdopen(fd2, m1);
3574 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3575 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003576 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003577 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3578 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003579 PyFile_SetBufSize(p1, 0);
3580 PyFile_SetBufSize(p2, 0);
3581 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003582 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003583 Py_XDECREF(p1);
3584 Py_XDECREF(p2);
3585 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003586 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003587 break;
3588 }
3589 }
3590
3591 if (n == POPEN_4) {
3592 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003593 hChildStdinRd,
3594 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003595 hChildStdoutWr,
3596 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003597 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003598 }
3599 else {
3600 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003601 hChildStdinRd,
3602 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003603 hChildStderrWr,
3604 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003605 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003606 }
3607
Mark Hammondb37a3732000-08-14 04:47:33 +00003608 /*
3609 * Insert the files we've created into the process dictionary
3610 * all referencing the list with the process handle and the
3611 * initial number of files (see description below in _PyPclose).
3612 * Since if _PyPclose later tried to wait on a process when all
3613 * handles weren't closed, it could create a deadlock with the
3614 * child, we spend some energy here to try to ensure that we
3615 * either insert all file handles into the dictionary or none
3616 * at all. It's a little clumsy with the various popen modes
3617 * and variable number of files involved.
3618 */
3619 if (!_PyPopenProcs) {
3620 _PyPopenProcs = PyDict_New();
3621 }
3622
3623 if (_PyPopenProcs) {
3624 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3625 int ins_rc[3];
3626
3627 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3628 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3629
3630 procObj = PyList_New(2);
3631 hProcessObj = PyLong_FromVoidPtr(hProcess);
3632 intObj = PyInt_FromLong(file_count);
3633
3634 if (procObj && hProcessObj && intObj) {
3635 PyList_SetItem(procObj,0,hProcessObj);
3636 PyList_SetItem(procObj,1,intObj);
3637
3638 fileObj[0] = PyLong_FromVoidPtr(f1);
3639 if (fileObj[0]) {
3640 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3641 fileObj[0],
3642 procObj);
3643 }
3644 if (file_count >= 2) {
3645 fileObj[1] = PyLong_FromVoidPtr(f2);
3646 if (fileObj[1]) {
3647 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3648 fileObj[1],
3649 procObj);
3650 }
3651 }
3652 if (file_count >= 3) {
3653 fileObj[2] = PyLong_FromVoidPtr(f3);
3654 if (fileObj[2]) {
3655 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3656 fileObj[2],
3657 procObj);
3658 }
3659 }
3660
3661 if (ins_rc[0] < 0 || !fileObj[0] ||
3662 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3663 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3664 /* Something failed - remove any dictionary
3665 * entries that did make it.
3666 */
3667 if (!ins_rc[0] && fileObj[0]) {
3668 PyDict_DelItem(_PyPopenProcs,
3669 fileObj[0]);
3670 }
3671 if (!ins_rc[1] && fileObj[1]) {
3672 PyDict_DelItem(_PyPopenProcs,
3673 fileObj[1]);
3674 }
3675 if (!ins_rc[2] && fileObj[2]) {
3676 PyDict_DelItem(_PyPopenProcs,
3677 fileObj[2]);
3678 }
3679 }
3680 }
Tim Peters5aa91602002-01-30 05:46:57 +00003681
Mark Hammondb37a3732000-08-14 04:47:33 +00003682 /*
3683 * Clean up our localized references for the dictionary keys
3684 * and value since PyDict_SetItem will Py_INCREF any copies
3685 * that got placed in the dictionary.
3686 */
3687 Py_XDECREF(procObj);
3688 Py_XDECREF(fileObj[0]);
3689 Py_XDECREF(fileObj[1]);
3690 Py_XDECREF(fileObj[2]);
3691 }
3692
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003693 /* Child is launched. Close the parents copy of those pipe
3694 * handles that only the child should have open. You need to
3695 * make sure that no handles to the write end of the output pipe
3696 * are maintained in this process or else the pipe will not close
3697 * when the child process exits and the ReadFile will hang. */
3698
3699 if (!CloseHandle(hChildStdinRd))
3700 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003701
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003702 if (!CloseHandle(hChildStdoutWr))
3703 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003704
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003705 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3706 return win32_error("CloseHandle", NULL);
3707
3708 return f;
3709}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003710
3711/*
3712 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3713 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003714 *
3715 * This function uses the _PyPopenProcs dictionary in order to map the
3716 * input file pointer to information about the process that was
3717 * originally created by the popen* call that created the file pointer.
3718 * The dictionary uses the file pointer as a key (with one entry
3719 * inserted for each file returned by the original popen* call) and a
3720 * single list object as the value for all files from a single call.
3721 * The list object contains the Win32 process handle at [0], and a file
3722 * count at [1], which is initialized to the total number of file
3723 * handles using that list.
3724 *
3725 * This function closes whichever handle it is passed, and decrements
3726 * the file count in the dictionary for the process handle pointed to
3727 * by this file. On the last close (when the file count reaches zero),
3728 * this function will wait for the child process and then return its
3729 * exit code as the result of the close() operation. This permits the
3730 * files to be closed in any order - it is always the close() of the
3731 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003732 */
Tim Peters736aa322000-09-01 06:51:24 +00003733
3734 /* RED_FLAG 31-Aug-2000 Tim
3735 * This is always called (today!) between a pair of
3736 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3737 * macros. So the thread running this has no valid thread state, as
3738 * far as Python is concerned. However, this calls some Python API
3739 * functions that cannot be called safely without a valid thread
3740 * state, in particular PyDict_GetItem.
3741 * As a temporary hack (although it may last for years ...), we
3742 * *rely* on not having a valid thread state in this function, in
3743 * order to create our own "from scratch".
3744 * This will deadlock if _PyPclose is ever called by a thread
3745 * holding the global lock.
3746 */
3747
Fredrik Lundh56055a42000-07-23 19:47:12 +00003748static int _PyPclose(FILE *file)
3749{
Fredrik Lundh20318932000-07-26 17:29:12 +00003750 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003751 DWORD exit_code;
3752 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003753 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3754 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003755#ifdef WITH_THREAD
3756 PyInterpreterState* pInterpreterState;
3757 PyThreadState* pThreadState;
3758#endif
3759
Fredrik Lundh20318932000-07-26 17:29:12 +00003760 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003761 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003762 */
3763 result = fclose(file);
3764
Tim Peters736aa322000-09-01 06:51:24 +00003765#ifdef WITH_THREAD
3766 /* Bootstrap a valid thread state into existence. */
3767 pInterpreterState = PyInterpreterState_New();
3768 if (!pInterpreterState) {
3769 /* Well, we're hosed now! We don't have a thread
3770 * state, so can't call a nice error routine, or raise
3771 * an exception. Just die.
3772 */
3773 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003774 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003775 return -1; /* unreachable */
3776 }
3777 pThreadState = PyThreadState_New(pInterpreterState);
3778 if (!pThreadState) {
3779 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003780 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003781 return -1; /* unreachable */
3782 }
3783 /* Grab the global lock. Note that this will deadlock if the
3784 * current thread already has the lock! (see RED_FLAG comments
3785 * before this function)
3786 */
3787 PyEval_RestoreThread(pThreadState);
3788#endif
3789
Fredrik Lundh56055a42000-07-23 19:47:12 +00003790 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003791 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3792 (procObj = PyDict_GetItem(_PyPopenProcs,
3793 fileObj)) != NULL &&
3794 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3795 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3796
3797 hProcess = PyLong_AsVoidPtr(hProcessObj);
3798 file_count = PyInt_AsLong(intObj);
3799
3800 if (file_count > 1) {
3801 /* Still other files referencing process */
3802 file_count--;
3803 PyList_SetItem(procObj,1,
3804 PyInt_FromLong(file_count));
3805 } else {
3806 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003807 if (result != EOF &&
3808 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3809 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003810 /* Possible truncation here in 16-bit environments, but
3811 * real exit codes are just the lower byte in any event.
3812 */
3813 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003814 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003815 /* Indicate failure - this will cause the file object
3816 * to raise an I/O error and translate the last Win32
3817 * error code from errno. We do have a problem with
3818 * last errors that overlap the normal errno table,
3819 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003820 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003821 if (result != EOF) {
3822 /* If the error wasn't from the fclose(), then
3823 * set errno for the file object error handling.
3824 */
3825 errno = GetLastError();
3826 }
3827 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003828 }
3829
3830 /* Free up the native handle at this point */
3831 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003832 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003833
Mark Hammondb37a3732000-08-14 04:47:33 +00003834 /* Remove this file pointer from dictionary */
3835 PyDict_DelItem(_PyPopenProcs, fileObj);
3836
3837 if (PyDict_Size(_PyPopenProcs) == 0) {
3838 Py_DECREF(_PyPopenProcs);
3839 _PyPopenProcs = NULL;
3840 }
3841
3842 } /* if object retrieval ok */
3843
3844 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003845 } /* if _PyPopenProcs */
3846
Tim Peters736aa322000-09-01 06:51:24 +00003847#ifdef WITH_THREAD
3848 /* Tear down the thread & interpreter states.
3849 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003850 * call the thread clear & delete functions, and indeed insist on
3851 * doing that themselves. The lock must be held during the clear, but
3852 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003853 */
3854 PyInterpreterState_Clear(pInterpreterState);
3855 PyEval_ReleaseThread(pThreadState);
3856 PyInterpreterState_Delete(pInterpreterState);
3857#endif
3858
Fredrik Lundh56055a42000-07-23 19:47:12 +00003859 return result;
3860}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003861
3862#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003864posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003865{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003866 char *name;
3867 char *mode = "r";
3868 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003869 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003870 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003871 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003872 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003873 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003874 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003875 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003876 if (fp == NULL)
3877 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003878 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003879 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003880 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003881 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003882}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003883
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003884#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003885#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003886
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003887
Guido van Rossumb6775db1994-08-01 11:34:53 +00003888#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003889PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003890"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003891Set the current process's user id.");
3892
Barry Warsaw53699e91996-12-10 23:23:01 +00003893static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003894posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003895{
3896 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003897 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003898 return NULL;
3899 if (setuid(uid) < 0)
3900 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003901 Py_INCREF(Py_None);
3902 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003903}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003904#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003905
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003906
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003907#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003908PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003909"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003910Set the current process's effective user id.");
3911
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003912static PyObject *
3913posix_seteuid (PyObject *self, PyObject *args)
3914{
3915 int euid;
3916 if (!PyArg_ParseTuple(args, "i", &euid)) {
3917 return NULL;
3918 } else if (seteuid(euid) < 0) {
3919 return posix_error();
3920 } else {
3921 Py_INCREF(Py_None);
3922 return Py_None;
3923 }
3924}
3925#endif /* HAVE_SETEUID */
3926
3927#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003928PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003929"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003930Set the current process's effective group id.");
3931
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003932static PyObject *
3933posix_setegid (PyObject *self, PyObject *args)
3934{
3935 int egid;
3936 if (!PyArg_ParseTuple(args, "i", &egid)) {
3937 return NULL;
3938 } else if (setegid(egid) < 0) {
3939 return posix_error();
3940 } else {
3941 Py_INCREF(Py_None);
3942 return Py_None;
3943 }
3944}
3945#endif /* HAVE_SETEGID */
3946
3947#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003948PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003949"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003950Set the current process's real and effective user ids.");
3951
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003952static PyObject *
3953posix_setreuid (PyObject *self, PyObject *args)
3954{
3955 int ruid, euid;
3956 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3957 return NULL;
3958 } else if (setreuid(ruid, euid) < 0) {
3959 return posix_error();
3960 } else {
3961 Py_INCREF(Py_None);
3962 return Py_None;
3963 }
3964}
3965#endif /* HAVE_SETREUID */
3966
3967#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003968PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003969"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003970Set the current process's real and effective group ids.");
3971
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003972static PyObject *
3973posix_setregid (PyObject *self, PyObject *args)
3974{
3975 int rgid, egid;
3976 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3977 return NULL;
3978 } else if (setregid(rgid, egid) < 0) {
3979 return posix_error();
3980 } else {
3981 Py_INCREF(Py_None);
3982 return Py_None;
3983 }
3984}
3985#endif /* HAVE_SETREGID */
3986
Guido van Rossumb6775db1994-08-01 11:34:53 +00003987#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003988PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003989"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003990Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003991
Barry Warsaw53699e91996-12-10 23:23:01 +00003992static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003993posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003994{
3995 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003996 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003997 return NULL;
3998 if (setgid(gid) < 0)
3999 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004000 Py_INCREF(Py_None);
4001 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004002}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004003#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004004
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004005#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004006PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004007"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004008Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004009
4010static PyObject *
4011posix_setgroups(PyObject *self, PyObject *args)
4012{
4013 PyObject *groups;
4014 int i, len;
4015 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004016
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004017 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4018 return NULL;
4019 if (!PySequence_Check(groups)) {
4020 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4021 return NULL;
4022 }
4023 len = PySequence_Size(groups);
4024 if (len > MAX_GROUPS) {
4025 PyErr_SetString(PyExc_ValueError, "too many groups");
4026 return NULL;
4027 }
4028 for(i = 0; i < len; i++) {
4029 PyObject *elem;
4030 elem = PySequence_GetItem(groups, i);
4031 if (!elem)
4032 return NULL;
4033 if (!PyInt_Check(elem)) {
4034 PyErr_SetString(PyExc_TypeError,
4035 "groups must be integers");
4036 Py_DECREF(elem);
4037 return NULL;
4038 }
4039 /* XXX: check that value fits into gid_t. */
4040 grouplist[i] = PyInt_AsLong(elem);
4041 Py_DECREF(elem);
4042 }
4043
4044 if (setgroups(len, grouplist) < 0)
4045 return posix_error();
4046 Py_INCREF(Py_None);
4047 return Py_None;
4048}
4049#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004050
Guido van Rossumb6775db1994-08-01 11:34:53 +00004051#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004052PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004053"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004054Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004055
Barry Warsaw53699e91996-12-10 23:23:01 +00004056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004057posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004058{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004059 int pid, options;
4060#ifdef UNION_WAIT
4061 union wait status;
4062#define status_i (status.w_status)
4063#else
4064 int status;
4065#define status_i status
4066#endif
4067 status_i = 0;
4068
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004069 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004070 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004071 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004072 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004073 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004074 if (pid == -1)
4075 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004076 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004077 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004078}
4079
Tim Petersab034fa2002-02-01 11:27:43 +00004080#elif defined(HAVE_CWAIT)
4081
4082/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004083PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004084"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004085"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004086
4087static PyObject *
4088posix_waitpid(PyObject *self, PyObject *args)
4089{
4090 int pid, options;
4091 int status;
4092
4093 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4094 return NULL;
4095 Py_BEGIN_ALLOW_THREADS
4096 pid = _cwait(&status, pid, options);
4097 Py_END_ALLOW_THREADS
4098 if (pid == -1)
4099 return posix_error();
4100 else
4101 /* shift the status left a byte so this is more like the
4102 POSIX waitpid */
4103 return Py_BuildValue("ii", pid, status << 8);
4104}
4105#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004106
Guido van Rossumad0ee831995-03-01 10:34:45 +00004107#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004108PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004109"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004110Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004111
Barry Warsaw53699e91996-12-10 23:23:01 +00004112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004113posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004114{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004115 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004116#ifdef UNION_WAIT
4117 union wait status;
4118#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004119#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004120 int status;
4121#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004122#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004123 if (!PyArg_ParseTuple(args, ":wait"))
4124 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004125 status_i = 0;
4126 Py_BEGIN_ALLOW_THREADS
4127 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004128 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004129 if (pid == -1)
4130 return posix_error();
4131 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004132 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004133#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004134}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004135#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004137
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004138PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004139"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004140Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004141
Barry Warsaw53699e91996-12-10 23:23:01 +00004142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004143posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004144{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004145#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004146 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004147#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004148 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004149#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004150}
4151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004152
Guido van Rossumb6775db1994-08-01 11:34:53 +00004153#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004154PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004155"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004156Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004157
Barry Warsaw53699e91996-12-10 23:23:01 +00004158static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004159posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004160{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004161 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004162 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004163 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004164 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004165 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004166 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004167 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004168 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004169 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004170 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004171 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004172}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004173#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004175
Guido van Rossumb6775db1994-08-01 11:34:53 +00004176#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004177PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004178"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004179Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004180
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004182posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004183{
Mark Hammondef8b6542001-05-13 08:04:26 +00004184 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004185}
4186#endif /* HAVE_SYMLINK */
4187
4188
4189#ifdef HAVE_TIMES
4190#ifndef HZ
4191#define HZ 60 /* Universal constant :-) */
4192#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004193
Guido van Rossumd48f2521997-12-05 22:19:34 +00004194#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4195static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004196system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004197{
4198 ULONG value = 0;
4199
4200 Py_BEGIN_ALLOW_THREADS
4201 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4202 Py_END_ALLOW_THREADS
4203
4204 return value;
4205}
4206
4207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004208posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004209{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004210 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004211 return NULL;
4212
4213 /* Currently Only Uptime is Provided -- Others Later */
4214 return Py_BuildValue("ddddd",
4215 (double)0 /* t.tms_utime / HZ */,
4216 (double)0 /* t.tms_stime / HZ */,
4217 (double)0 /* t.tms_cutime / HZ */,
4218 (double)0 /* t.tms_cstime / HZ */,
4219 (double)system_uptime() / 1000);
4220}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004221#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004223posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004224{
4225 struct tms t;
4226 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004227 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004228 return NULL;
4229 errno = 0;
4230 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004231 if (c == (clock_t) -1)
4232 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004233 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004234 (double)t.tms_utime / HZ,
4235 (double)t.tms_stime / HZ,
4236 (double)t.tms_cutime / HZ,
4237 (double)t.tms_cstime / HZ,
4238 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004239}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004240#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004241#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004242
4243
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004244#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004245#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004246static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004247posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004248{
4249 FILETIME create, exit, kernel, user;
4250 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004251 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004252 return NULL;
4253 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004254 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4255 /* The fields of a FILETIME structure are the hi and lo part
4256 of a 64-bit value expressed in 100 nanosecond units.
4257 1e7 is one second in such units; 1e-7 the inverse.
4258 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4259 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004260 return Py_BuildValue(
4261 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004262 (double)(kernel.dwHighDateTime*429.4967296 +
4263 kernel.dwLowDateTime*1e-7),
4264 (double)(user.dwHighDateTime*429.4967296 +
4265 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004266 (double)0,
4267 (double)0,
4268 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004269}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004270#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004271
4272#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004273PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004274"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004275Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004276#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004278
Guido van Rossumb6775db1994-08-01 11:34:53 +00004279#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004280PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004281"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004282Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004283
Barry Warsaw53699e91996-12-10 23:23:01 +00004284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004285posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004286{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004287 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004288 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004289 if (setsid() < 0)
4290 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004291 Py_INCREF(Py_None);
4292 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004293}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004294#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004295
Guido van Rossumb6775db1994-08-01 11:34:53 +00004296#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004297PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004298"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004299Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004300
Barry Warsaw53699e91996-12-10 23:23:01 +00004301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004302posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004303{
4304 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004305 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004306 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004307 if (setpgid(pid, pgrp) < 0)
4308 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004309 Py_INCREF(Py_None);
4310 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004311}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004312#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004313
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004314
Guido van Rossumb6775db1994-08-01 11:34:53 +00004315#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004316PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004317"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004318Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004319
Barry Warsaw53699e91996-12-10 23:23:01 +00004320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004321posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004322{
4323 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004324 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004325 return NULL;
4326 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004327 if (pgid < 0)
4328 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004329 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004330}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004331#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004332
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004333
Guido van Rossumb6775db1994-08-01 11:34:53 +00004334#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004335PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004336"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004337Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004338
Barry Warsaw53699e91996-12-10 23:23:01 +00004339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004340posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004341{
4342 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004343 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004344 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004345 if (tcsetpgrp(fd, pgid) < 0)
4346 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004347 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004348 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004349}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004350#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004351
Guido van Rossum687dd131993-05-17 08:34:16 +00004352/* Functions acting on file descriptors */
4353
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004354PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004355"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004356Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004357
Barry Warsaw53699e91996-12-10 23:23:01 +00004358static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004359posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004360{
Mark Hammondef8b6542001-05-13 08:04:26 +00004361 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004362 int flag;
4363 int mode = 0777;
4364 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004365 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004366 Py_FileSystemDefaultEncoding, &file,
4367 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004368 return NULL;
4369
Barry Warsaw53699e91996-12-10 23:23:01 +00004370 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004371 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004372 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004373 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004374 return posix_error_with_allocated_filename(file);
4375 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004376 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004377}
4378
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004379
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004380PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004381"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004382Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004383
Barry Warsaw53699e91996-12-10 23:23:01 +00004384static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004385posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004386{
4387 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004388 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004389 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004390 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004391 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004392 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004393 if (res < 0)
4394 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004395 Py_INCREF(Py_None);
4396 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004397}
4398
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004399
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004400PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004401"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004402Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004403
Barry Warsaw53699e91996-12-10 23:23:01 +00004404static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004405posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004406{
4407 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004408 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004409 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004410 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004411 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004412 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004413 if (fd < 0)
4414 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004415 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004416}
4417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004418
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004419PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004420"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004421Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004422
Barry Warsaw53699e91996-12-10 23:23:01 +00004423static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004424posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004425{
4426 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004427 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004428 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004429 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004430 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004431 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004432 if (res < 0)
4433 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004434 Py_INCREF(Py_None);
4435 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004436}
4437
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004438
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004439PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004440"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004441Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004442
Barry Warsaw53699e91996-12-10 23:23:01 +00004443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004444posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004445{
4446 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004447#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004448 LONG_LONG pos, res;
4449#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004450 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004451#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004452 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004453 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004454 return NULL;
4455#ifdef SEEK_SET
4456 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4457 switch (how) {
4458 case 0: how = SEEK_SET; break;
4459 case 1: how = SEEK_CUR; break;
4460 case 2: how = SEEK_END; break;
4461 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004462#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004463
4464#if !defined(HAVE_LARGEFILE_SUPPORT)
4465 pos = PyInt_AsLong(posobj);
4466#else
4467 pos = PyLong_Check(posobj) ?
4468 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4469#endif
4470 if (PyErr_Occurred())
4471 return NULL;
4472
Barry Warsaw53699e91996-12-10 23:23:01 +00004473 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004474#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004475 res = _lseeki64(fd, pos, how);
4476#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004477 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004478#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004479 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004480 if (res < 0)
4481 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004482
4483#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004484 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004485#else
4486 return PyLong_FromLongLong(res);
4487#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004488}
4489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004490
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004491PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004492"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004493Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004494
Barry Warsaw53699e91996-12-10 23:23:01 +00004495static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004496posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004497{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004498 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004499 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004500 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004501 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004502 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004503 if (buffer == NULL)
4504 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004505 Py_BEGIN_ALLOW_THREADS
4506 n = read(fd, PyString_AsString(buffer), size);
4507 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004508 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004509 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004510 return posix_error();
4511 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004512 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004513 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004514 return buffer;
4515}
4516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004517
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004518PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004519"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004520Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004521
Barry Warsaw53699e91996-12-10 23:23:01 +00004522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004523posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004524{
4525 int fd, size;
4526 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004527 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004528 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004529 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004530 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004531 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004532 if (size < 0)
4533 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004534 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004535}
4536
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004537
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004538PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004539"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004540Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004541
Barry Warsaw53699e91996-12-10 23:23:01 +00004542static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004543posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004544{
4545 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004546 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004547 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004548 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004549 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004550 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004551 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004552 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004553 if (res != 0)
4554 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004555
Fred Drake699f3522000-06-29 21:12:41 +00004556 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004557}
4558
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004559
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004560PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004561"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004562Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004563
Barry Warsaw53699e91996-12-10 23:23:01 +00004564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004565posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004566{
Guido van Rossum687dd131993-05-17 08:34:16 +00004567 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004568 char *mode = "r";
4569 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004570 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004571 PyObject *f;
4572 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004573 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004574
Barry Warsaw53699e91996-12-10 23:23:01 +00004575 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004576 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004577 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004578 if (fp == NULL)
4579 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004580 f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004581 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004582 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004583 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004584}
4585
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004586PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004587"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004588Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004589connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004590
4591static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004592posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004593{
4594 int fd;
4595 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4596 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004597 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004598}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004599
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004600#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004601PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004602"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004603Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004604
Barry Warsaw53699e91996-12-10 23:23:01 +00004605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004606posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004607{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004608#if defined(PYOS_OS2)
4609 HFILE read, write;
4610 APIRET rc;
4611
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004612 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004613 return NULL;
4614
4615 Py_BEGIN_ALLOW_THREADS
4616 rc = DosCreatePipe( &read, &write, 4096);
4617 Py_END_ALLOW_THREADS
4618 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004619 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004620
4621 return Py_BuildValue("(ii)", read, write);
4622#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004623#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004624 int fds[2];
4625 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004626 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004627 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004628 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004629 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004630 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004631 if (res != 0)
4632 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004633 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004634#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004635 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004636 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004637 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004638 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004639 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004640 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004641 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004642 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004643 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004644 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004645 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4646 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004647 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004648#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004649#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004650}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004651#endif /* HAVE_PIPE */
4652
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004653
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004654#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004655PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004656"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004657Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004658
Barry Warsaw53699e91996-12-10 23:23:01 +00004659static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004660posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004661{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004662 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004663 int mode = 0666;
4664 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004665 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004666 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004667 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004668 res = mkfifo(filename, mode);
4669 Py_END_ALLOW_THREADS
4670 if (res < 0)
4671 return posix_error();
4672 Py_INCREF(Py_None);
4673 return Py_None;
4674}
4675#endif
4676
4677
Neal Norwitz11690112002-07-30 01:08:28 +00004678#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004679PyDoc_STRVAR(posix_mknod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004680"mknod(filename, [, mode=0600, major, minor])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004681Create a filesystem node (file, device special file or named pipe)\n\
4682named filename. mode specifies both the permissions to use and the\n\
4683type of node to be created, being combined (bitwise OR) with one of\n\
4684S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4685major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004686they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004687
4688
4689static PyObject *
4690posix_mknod(PyObject *self, PyObject *args)
4691{
4692 char *filename;
4693 int mode = 0600;
4694 int major = 0;
4695 int minor = 0;
4696 int res;
4697 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4698 &mode, &major, &minor))
4699 return NULL;
4700 Py_BEGIN_ALLOW_THREADS
4701 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004702 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004703 if (res < 0)
4704 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004705 Py_INCREF(Py_None);
4706 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004707}
4708#endif
4709
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004710
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004711#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004712PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004713"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004714Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004715
Barry Warsaw53699e91996-12-10 23:23:01 +00004716static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004717posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004718{
4719 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004720 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004721 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004722 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004723
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004724 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004725 return NULL;
4726
4727#if !defined(HAVE_LARGEFILE_SUPPORT)
4728 length = PyInt_AsLong(lenobj);
4729#else
4730 length = PyLong_Check(lenobj) ?
4731 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4732#endif
4733 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004734 return NULL;
4735
Barry Warsaw53699e91996-12-10 23:23:01 +00004736 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004737 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004738 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004739 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004740 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004741 return NULL;
4742 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004743 Py_INCREF(Py_None);
4744 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004745}
4746#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004747
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004748#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004749PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004750"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004751Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004752
Fred Drake762e2061999-08-26 17:23:54 +00004753/* Save putenv() parameters as values here, so we can collect them when they
4754 * get re-set with another call for the same key. */
4755static PyObject *posix_putenv_garbage;
4756
Tim Peters5aa91602002-01-30 05:46:57 +00004757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004758posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004759{
4760 char *s1, *s2;
4761 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004762 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004763 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004764
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004765 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004766 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004767
4768#if defined(PYOS_OS2)
4769 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4770 APIRET rc;
4771
4772 if (strlen(s2) == 0) /* If New Value is an Empty String */
4773 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4774
4775 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4776 if (rc != NO_ERROR)
4777 return os2_error(rc);
4778
4779 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4780 APIRET rc;
4781
4782 if (strlen(s2) == 0) /* If New Value is an Empty String */
4783 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4784
4785 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4786 if (rc != NO_ERROR)
4787 return os2_error(rc);
4788 } else {
4789#endif
4790
Fred Drake762e2061999-08-26 17:23:54 +00004791 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004792 len = strlen(s1) + strlen(s2) + 2;
4793 /* len includes space for a trailing \0; the size arg to
4794 PyString_FromStringAndSize does not count that */
4795 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004796 if (newstr == NULL)
4797 return PyErr_NoMemory();
4798 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004799 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004800 if (putenv(new)) {
4801 posix_error();
4802 return NULL;
4803 }
Fred Drake762e2061999-08-26 17:23:54 +00004804 /* Install the first arg and newstr in posix_putenv_garbage;
4805 * this will cause previous value to be collected. This has to
4806 * happen after the real putenv() call because the old value
4807 * was still accessible until then. */
4808 if (PyDict_SetItem(posix_putenv_garbage,
4809 PyTuple_GET_ITEM(args, 0), newstr)) {
4810 /* really not much we can do; just leak */
4811 PyErr_Clear();
4812 }
4813 else {
4814 Py_DECREF(newstr);
4815 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004816
4817#if defined(PYOS_OS2)
4818 }
4819#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004820 Py_INCREF(Py_None);
4821 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004822}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004823#endif /* putenv */
4824
Guido van Rossumc524d952001-10-19 01:31:59 +00004825#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004826PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004827"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004828Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00004829
4830static PyObject *
4831posix_unsetenv(PyObject *self, PyObject *args)
4832{
4833 char *s1;
4834
4835 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4836 return NULL;
4837
4838 unsetenv(s1);
4839
4840 /* Remove the key from posix_putenv_garbage;
4841 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004842 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004843 * old value was still accessible until then.
4844 */
4845 if (PyDict_DelItem(posix_putenv_garbage,
4846 PyTuple_GET_ITEM(args, 0))) {
4847 /* really not much we can do; just leak */
4848 PyErr_Clear();
4849 }
4850
4851 Py_INCREF(Py_None);
4852 return Py_None;
4853}
4854#endif /* unsetenv */
4855
Guido van Rossumb6a47161997-09-15 22:54:34 +00004856#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004857PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004858"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004859Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004860
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004862posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004863{
4864 int code;
4865 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004866 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004867 return NULL;
4868 message = strerror(code);
4869 if (message == NULL) {
4870 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004871 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004872 return NULL;
4873 }
4874 return PyString_FromString(message);
4875}
4876#endif /* strerror */
4877
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004878
Guido van Rossumc9641791998-08-04 15:26:23 +00004879#ifdef HAVE_SYS_WAIT_H
4880
Fred Drake106c1a02002-04-23 15:58:02 +00004881#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004882PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004883"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004884Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00004885
4886static PyObject *
4887posix_WCOREDUMP(PyObject *self, PyObject *args)
4888{
4889#ifdef UNION_WAIT
4890 union wait status;
4891#define status_i (status.w_status)
4892#else
4893 int status;
4894#define status_i status
4895#endif
4896 status_i = 0;
4897
4898 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4899 {
4900 return NULL;
4901 }
4902
4903 return PyBool_FromLong(WCOREDUMP(status));
4904#undef status_i
4905}
4906#endif /* WCOREDUMP */
4907
4908#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004910"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004911Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004912job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00004913
4914static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004915posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004916{
4917#ifdef UNION_WAIT
4918 union wait status;
4919#define status_i (status.w_status)
4920#else
4921 int status;
4922#define status_i status
4923#endif
4924 status_i = 0;
4925
4926 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4927 {
4928 return NULL;
4929 }
4930
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004931 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004932#undef status_i
4933}
4934#endif /* WIFCONTINUED */
4935
Guido van Rossumc9641791998-08-04 15:26:23 +00004936#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004937PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004938"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004939Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004940
4941static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004942posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004943{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004944#ifdef UNION_WAIT
4945 union wait status;
4946#define status_i (status.w_status)
4947#else
4948 int status;
4949#define status_i status
4950#endif
4951 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004952
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004953 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004954 {
4955 return NULL;
4956 }
Tim Peters5aa91602002-01-30 05:46:57 +00004957
Fred Drake106c1a02002-04-23 15:58:02 +00004958 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004959#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004960}
4961#endif /* WIFSTOPPED */
4962
4963#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004964PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004965"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004966Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004967
4968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004969posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004970{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004971#ifdef UNION_WAIT
4972 union wait status;
4973#define status_i (status.w_status)
4974#else
4975 int status;
4976#define status_i status
4977#endif
4978 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004979
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004980 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004981 {
4982 return NULL;
4983 }
Tim Peters5aa91602002-01-30 05:46:57 +00004984
Fred Drake106c1a02002-04-23 15:58:02 +00004985 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004986#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004987}
4988#endif /* WIFSIGNALED */
4989
4990#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004991PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004992"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00004993Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004995
4996static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004997posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004998{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004999#ifdef UNION_WAIT
5000 union wait status;
5001#define status_i (status.w_status)
5002#else
5003 int status;
5004#define status_i status
5005#endif
5006 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005007
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005008 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005009 {
5010 return NULL;
5011 }
Tim Peters5aa91602002-01-30 05:46:57 +00005012
Fred Drake106c1a02002-04-23 15:58:02 +00005013 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005014#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005015}
5016#endif /* WIFEXITED */
5017
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005018#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005019PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005020"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005021Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005022
5023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005024posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005025{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005026#ifdef UNION_WAIT
5027 union wait status;
5028#define status_i (status.w_status)
5029#else
5030 int status;
5031#define status_i status
5032#endif
5033 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005034
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005035 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005036 {
5037 return NULL;
5038 }
Tim Peters5aa91602002-01-30 05:46:57 +00005039
Guido van Rossumc9641791998-08-04 15:26:23 +00005040 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005041#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005042}
5043#endif /* WEXITSTATUS */
5044
5045#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005046PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005047"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005048Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005049value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005050
5051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005052posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005053{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005054#ifdef UNION_WAIT
5055 union wait status;
5056#define status_i (status.w_status)
5057#else
5058 int status;
5059#define status_i status
5060#endif
5061 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005062
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005063 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005064 {
5065 return NULL;
5066 }
Tim Peters5aa91602002-01-30 05:46:57 +00005067
Guido van Rossumc9641791998-08-04 15:26:23 +00005068 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005069#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005070}
5071#endif /* WTERMSIG */
5072
5073#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005074PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005075"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005076Return the signal that stopped the process that provided\n\
5077the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005078
5079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005080posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005081{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005082#ifdef UNION_WAIT
5083 union wait status;
5084#define status_i (status.w_status)
5085#else
5086 int status;
5087#define status_i status
5088#endif
5089 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005090
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005091 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005092 {
5093 return NULL;
5094 }
Tim Peters5aa91602002-01-30 05:46:57 +00005095
Guido van Rossumc9641791998-08-04 15:26:23 +00005096 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005097#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005098}
5099#endif /* WSTOPSIG */
5100
5101#endif /* HAVE_SYS_WAIT_H */
5102
5103
Guido van Rossum94f6f721999-01-06 18:42:14 +00005104#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005105#ifdef _SCO_DS
5106/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5107 needed definitions in sys/statvfs.h */
5108#define _SVID3
5109#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005110#include <sys/statvfs.h>
5111
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005112static PyObject*
5113_pystatvfs_fromstructstatvfs(struct statvfs st) {
5114 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5115 if (v == NULL)
5116 return NULL;
5117
5118#if !defined(HAVE_LARGEFILE_SUPPORT)
5119 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5120 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5121 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5122 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5123 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5124 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5125 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5126 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5127 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5128 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5129#else
5130 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5131 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005132 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005133 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005134 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005135 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5136 PyStructSequence_SET_ITEM(v, 4,
5137 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005138 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005139 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005140 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005141 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005142 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005143 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5144 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5145 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5146#endif
5147
5148 return v;
5149}
5150
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005151PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005152"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005153Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005154
5155static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005156posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005157{
5158 int fd, res;
5159 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005160
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005161 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005162 return NULL;
5163 Py_BEGIN_ALLOW_THREADS
5164 res = fstatvfs(fd, &st);
5165 Py_END_ALLOW_THREADS
5166 if (res != 0)
5167 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005168
5169 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005170}
5171#endif /* HAVE_FSTATVFS */
5172
5173
5174#if defined(HAVE_STATVFS)
5175#include <sys/statvfs.h>
5176
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005177PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005178"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005179Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005180
5181static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005182posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005183{
5184 char *path;
5185 int res;
5186 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005187 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005188 return NULL;
5189 Py_BEGIN_ALLOW_THREADS
5190 res = statvfs(path, &st);
5191 Py_END_ALLOW_THREADS
5192 if (res != 0)
5193 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005194
5195 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005196}
5197#endif /* HAVE_STATVFS */
5198
5199
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005200#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005201PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005202"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005203Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005204The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005205or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005206
5207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005208posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005209{
5210 PyObject *result = NULL;
5211 char *dir = NULL;
5212 char *pfx = NULL;
5213 char *name;
5214
5215 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5216 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005217
5218 if (PyErr_Warn(PyExc_RuntimeWarning,
5219 "tempnam is a potential security risk to your program") < 0)
5220 return NULL;
5221
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005222#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005223 name = _tempnam(dir, pfx);
5224#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005225 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005226#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005227 if (name == NULL)
5228 return PyErr_NoMemory();
5229 result = PyString_FromString(name);
5230 free(name);
5231 return result;
5232}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005233#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005234
5235
5236#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005237PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005238"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005239Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005240
5241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005242posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005243{
5244 FILE *fp;
5245
5246 if (!PyArg_ParseTuple(args, ":tmpfile"))
5247 return NULL;
5248 fp = tmpfile();
5249 if (fp == NULL)
5250 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005251 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005252}
5253#endif
5254
5255
5256#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005257PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005258"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005259Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005260
5261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005262posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005263{
5264 char buffer[L_tmpnam];
5265 char *name;
5266
5267 if (!PyArg_ParseTuple(args, ":tmpnam"))
5268 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005269
5270 if (PyErr_Warn(PyExc_RuntimeWarning,
5271 "tmpnam is a potential security risk to your program") < 0)
5272 return NULL;
5273
Greg Wardb48bc172000-03-01 21:51:56 +00005274#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005275 name = tmpnam_r(buffer);
5276#else
5277 name = tmpnam(buffer);
5278#endif
5279 if (name == NULL) {
5280 PyErr_SetObject(PyExc_OSError,
5281 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005282#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005283 "unexpected NULL from tmpnam_r"
5284#else
5285 "unexpected NULL from tmpnam"
5286#endif
5287 ));
5288 return NULL;
5289 }
5290 return PyString_FromString(buffer);
5291}
5292#endif
5293
5294
Fred Drakec9680921999-12-13 16:37:25 +00005295/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5296 * It maps strings representing configuration variable names to
5297 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005298 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005299 * rarely-used constants. There are three separate tables that use
5300 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005301 *
5302 * This code is always included, even if none of the interfaces that
5303 * need it are included. The #if hackery needed to avoid it would be
5304 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005305 */
5306struct constdef {
5307 char *name;
5308 long value;
5309};
5310
Fred Drake12c6e2d1999-12-14 21:25:03 +00005311static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005312conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5313 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005314{
5315 if (PyInt_Check(arg)) {
5316 *valuep = PyInt_AS_LONG(arg);
5317 return 1;
5318 }
5319 if (PyString_Check(arg)) {
5320 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005321 size_t lo = 0;
5322 size_t mid;
5323 size_t hi = tablesize;
5324 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005325 char *confname = PyString_AS_STRING(arg);
5326 while (lo < hi) {
5327 mid = (lo + hi) / 2;
5328 cmp = strcmp(confname, table[mid].name);
5329 if (cmp < 0)
5330 hi = mid;
5331 else if (cmp > 0)
5332 lo = mid + 1;
5333 else {
5334 *valuep = table[mid].value;
5335 return 1;
5336 }
5337 }
5338 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5339 }
5340 else
5341 PyErr_SetString(PyExc_TypeError,
5342 "configuration names must be strings or integers");
5343 return 0;
5344}
5345
5346
5347#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5348static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005349#ifdef _PC_ABI_AIO_XFER_MAX
5350 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5351#endif
5352#ifdef _PC_ABI_ASYNC_IO
5353 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5354#endif
Fred Drakec9680921999-12-13 16:37:25 +00005355#ifdef _PC_ASYNC_IO
5356 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5357#endif
5358#ifdef _PC_CHOWN_RESTRICTED
5359 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5360#endif
5361#ifdef _PC_FILESIZEBITS
5362 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5363#endif
5364#ifdef _PC_LAST
5365 {"PC_LAST", _PC_LAST},
5366#endif
5367#ifdef _PC_LINK_MAX
5368 {"PC_LINK_MAX", _PC_LINK_MAX},
5369#endif
5370#ifdef _PC_MAX_CANON
5371 {"PC_MAX_CANON", _PC_MAX_CANON},
5372#endif
5373#ifdef _PC_MAX_INPUT
5374 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5375#endif
5376#ifdef _PC_NAME_MAX
5377 {"PC_NAME_MAX", _PC_NAME_MAX},
5378#endif
5379#ifdef _PC_NO_TRUNC
5380 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5381#endif
5382#ifdef _PC_PATH_MAX
5383 {"PC_PATH_MAX", _PC_PATH_MAX},
5384#endif
5385#ifdef _PC_PIPE_BUF
5386 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5387#endif
5388#ifdef _PC_PRIO_IO
5389 {"PC_PRIO_IO", _PC_PRIO_IO},
5390#endif
5391#ifdef _PC_SOCK_MAXBUF
5392 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5393#endif
5394#ifdef _PC_SYNC_IO
5395 {"PC_SYNC_IO", _PC_SYNC_IO},
5396#endif
5397#ifdef _PC_VDISABLE
5398 {"PC_VDISABLE", _PC_VDISABLE},
5399#endif
5400};
5401
Fred Drakec9680921999-12-13 16:37:25 +00005402static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005403conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005404{
5405 return conv_confname(arg, valuep, posix_constants_pathconf,
5406 sizeof(posix_constants_pathconf)
5407 / sizeof(struct constdef));
5408}
5409#endif
5410
5411#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005412PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005413"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005414Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005415If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005416
5417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005418posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005419{
5420 PyObject *result = NULL;
5421 int name, fd;
5422
Fred Drake12c6e2d1999-12-14 21:25:03 +00005423 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5424 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005425 long limit;
5426
5427 errno = 0;
5428 limit = fpathconf(fd, name);
5429 if (limit == -1 && errno != 0)
5430 posix_error();
5431 else
5432 result = PyInt_FromLong(limit);
5433 }
5434 return result;
5435}
5436#endif
5437
5438
5439#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005440PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005441"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005442Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005443If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005444
5445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005446posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005447{
5448 PyObject *result = NULL;
5449 int name;
5450 char *path;
5451
5452 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5453 conv_path_confname, &name)) {
5454 long limit;
5455
5456 errno = 0;
5457 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005458 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005459 if (errno == EINVAL)
5460 /* could be a path or name problem */
5461 posix_error();
5462 else
5463 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005464 }
Fred Drakec9680921999-12-13 16:37:25 +00005465 else
5466 result = PyInt_FromLong(limit);
5467 }
5468 return result;
5469}
5470#endif
5471
5472#ifdef HAVE_CONFSTR
5473static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005474#ifdef _CS_ARCHITECTURE
5475 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5476#endif
5477#ifdef _CS_HOSTNAME
5478 {"CS_HOSTNAME", _CS_HOSTNAME},
5479#endif
5480#ifdef _CS_HW_PROVIDER
5481 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5482#endif
5483#ifdef _CS_HW_SERIAL
5484 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5485#endif
5486#ifdef _CS_INITTAB_NAME
5487 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5488#endif
Fred Drakec9680921999-12-13 16:37:25 +00005489#ifdef _CS_LFS64_CFLAGS
5490 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5491#endif
5492#ifdef _CS_LFS64_LDFLAGS
5493 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5494#endif
5495#ifdef _CS_LFS64_LIBS
5496 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5497#endif
5498#ifdef _CS_LFS64_LINTFLAGS
5499 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5500#endif
5501#ifdef _CS_LFS_CFLAGS
5502 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5503#endif
5504#ifdef _CS_LFS_LDFLAGS
5505 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5506#endif
5507#ifdef _CS_LFS_LIBS
5508 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5509#endif
5510#ifdef _CS_LFS_LINTFLAGS
5511 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5512#endif
Fred Draked86ed291999-12-15 15:34:33 +00005513#ifdef _CS_MACHINE
5514 {"CS_MACHINE", _CS_MACHINE},
5515#endif
Fred Drakec9680921999-12-13 16:37:25 +00005516#ifdef _CS_PATH
5517 {"CS_PATH", _CS_PATH},
5518#endif
Fred Draked86ed291999-12-15 15:34:33 +00005519#ifdef _CS_RELEASE
5520 {"CS_RELEASE", _CS_RELEASE},
5521#endif
5522#ifdef _CS_SRPC_DOMAIN
5523 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5524#endif
5525#ifdef _CS_SYSNAME
5526 {"CS_SYSNAME", _CS_SYSNAME},
5527#endif
5528#ifdef _CS_VERSION
5529 {"CS_VERSION", _CS_VERSION},
5530#endif
Fred Drakec9680921999-12-13 16:37:25 +00005531#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5532 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5533#endif
5534#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5535 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5536#endif
5537#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5538 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5539#endif
5540#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5541 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5542#endif
5543#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5544 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5545#endif
5546#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5547 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5548#endif
5549#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5550 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5551#endif
5552#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5553 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5554#endif
5555#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5556 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5557#endif
5558#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5559 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5560#endif
5561#ifdef _CS_XBS5_LP64_OFF64_LIBS
5562 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5563#endif
5564#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5565 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5566#endif
5567#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5568 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5569#endif
5570#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5571 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5572#endif
5573#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5574 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5575#endif
5576#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5577 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5578#endif
Fred Draked86ed291999-12-15 15:34:33 +00005579#ifdef _MIPS_CS_AVAIL_PROCESSORS
5580 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5581#endif
5582#ifdef _MIPS_CS_BASE
5583 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5584#endif
5585#ifdef _MIPS_CS_HOSTID
5586 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5587#endif
5588#ifdef _MIPS_CS_HW_NAME
5589 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5590#endif
5591#ifdef _MIPS_CS_NUM_PROCESSORS
5592 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5593#endif
5594#ifdef _MIPS_CS_OSREL_MAJ
5595 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5596#endif
5597#ifdef _MIPS_CS_OSREL_MIN
5598 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5599#endif
5600#ifdef _MIPS_CS_OSREL_PATCH
5601 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5602#endif
5603#ifdef _MIPS_CS_OS_NAME
5604 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5605#endif
5606#ifdef _MIPS_CS_OS_PROVIDER
5607 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5608#endif
5609#ifdef _MIPS_CS_PROCESSORS
5610 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5611#endif
5612#ifdef _MIPS_CS_SERIAL
5613 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5614#endif
5615#ifdef _MIPS_CS_VENDOR
5616 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5617#endif
Fred Drakec9680921999-12-13 16:37:25 +00005618};
5619
5620static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005621conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005622{
5623 return conv_confname(arg, valuep, posix_constants_confstr,
5624 sizeof(posix_constants_confstr)
5625 / sizeof(struct constdef));
5626}
5627
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005628PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005629"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005630Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005631
5632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005633posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005634{
5635 PyObject *result = NULL;
5636 int name;
5637 char buffer[64];
5638
5639 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5640 int len = confstr(name, buffer, sizeof(buffer));
5641
Fred Drakec9680921999-12-13 16:37:25 +00005642 errno = 0;
5643 if (len == 0) {
5644 if (errno != 0)
5645 posix_error();
5646 else
5647 result = PyString_FromString("");
5648 }
5649 else {
5650 if (len >= sizeof(buffer)) {
5651 result = PyString_FromStringAndSize(NULL, len);
5652 if (result != NULL)
5653 confstr(name, PyString_AS_STRING(result), len+1);
5654 }
5655 else
5656 result = PyString_FromString(buffer);
5657 }
5658 }
5659 return result;
5660}
5661#endif
5662
5663
5664#ifdef HAVE_SYSCONF
5665static struct constdef posix_constants_sysconf[] = {
5666#ifdef _SC_2_CHAR_TERM
5667 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5668#endif
5669#ifdef _SC_2_C_BIND
5670 {"SC_2_C_BIND", _SC_2_C_BIND},
5671#endif
5672#ifdef _SC_2_C_DEV
5673 {"SC_2_C_DEV", _SC_2_C_DEV},
5674#endif
5675#ifdef _SC_2_C_VERSION
5676 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5677#endif
5678#ifdef _SC_2_FORT_DEV
5679 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5680#endif
5681#ifdef _SC_2_FORT_RUN
5682 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5683#endif
5684#ifdef _SC_2_LOCALEDEF
5685 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5686#endif
5687#ifdef _SC_2_SW_DEV
5688 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5689#endif
5690#ifdef _SC_2_UPE
5691 {"SC_2_UPE", _SC_2_UPE},
5692#endif
5693#ifdef _SC_2_VERSION
5694 {"SC_2_VERSION", _SC_2_VERSION},
5695#endif
Fred Draked86ed291999-12-15 15:34:33 +00005696#ifdef _SC_ABI_ASYNCHRONOUS_IO
5697 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5698#endif
5699#ifdef _SC_ACL
5700 {"SC_ACL", _SC_ACL},
5701#endif
Fred Drakec9680921999-12-13 16:37:25 +00005702#ifdef _SC_AIO_LISTIO_MAX
5703 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5704#endif
Fred Drakec9680921999-12-13 16:37:25 +00005705#ifdef _SC_AIO_MAX
5706 {"SC_AIO_MAX", _SC_AIO_MAX},
5707#endif
5708#ifdef _SC_AIO_PRIO_DELTA_MAX
5709 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5710#endif
5711#ifdef _SC_ARG_MAX
5712 {"SC_ARG_MAX", _SC_ARG_MAX},
5713#endif
5714#ifdef _SC_ASYNCHRONOUS_IO
5715 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5716#endif
5717#ifdef _SC_ATEXIT_MAX
5718 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5719#endif
Fred Draked86ed291999-12-15 15:34:33 +00005720#ifdef _SC_AUDIT
5721 {"SC_AUDIT", _SC_AUDIT},
5722#endif
Fred Drakec9680921999-12-13 16:37:25 +00005723#ifdef _SC_AVPHYS_PAGES
5724 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5725#endif
5726#ifdef _SC_BC_BASE_MAX
5727 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5728#endif
5729#ifdef _SC_BC_DIM_MAX
5730 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5731#endif
5732#ifdef _SC_BC_SCALE_MAX
5733 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5734#endif
5735#ifdef _SC_BC_STRING_MAX
5736 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5737#endif
Fred Draked86ed291999-12-15 15:34:33 +00005738#ifdef _SC_CAP
5739 {"SC_CAP", _SC_CAP},
5740#endif
Fred Drakec9680921999-12-13 16:37:25 +00005741#ifdef _SC_CHARCLASS_NAME_MAX
5742 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5743#endif
5744#ifdef _SC_CHAR_BIT
5745 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5746#endif
5747#ifdef _SC_CHAR_MAX
5748 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5749#endif
5750#ifdef _SC_CHAR_MIN
5751 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5752#endif
5753#ifdef _SC_CHILD_MAX
5754 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5755#endif
5756#ifdef _SC_CLK_TCK
5757 {"SC_CLK_TCK", _SC_CLK_TCK},
5758#endif
5759#ifdef _SC_COHER_BLKSZ
5760 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5761#endif
5762#ifdef _SC_COLL_WEIGHTS_MAX
5763 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5764#endif
5765#ifdef _SC_DCACHE_ASSOC
5766 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5767#endif
5768#ifdef _SC_DCACHE_BLKSZ
5769 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5770#endif
5771#ifdef _SC_DCACHE_LINESZ
5772 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5773#endif
5774#ifdef _SC_DCACHE_SZ
5775 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5776#endif
5777#ifdef _SC_DCACHE_TBLKSZ
5778 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5779#endif
5780#ifdef _SC_DELAYTIMER_MAX
5781 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5782#endif
5783#ifdef _SC_EQUIV_CLASS_MAX
5784 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5785#endif
5786#ifdef _SC_EXPR_NEST_MAX
5787 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5788#endif
5789#ifdef _SC_FSYNC
5790 {"SC_FSYNC", _SC_FSYNC},
5791#endif
5792#ifdef _SC_GETGR_R_SIZE_MAX
5793 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5794#endif
5795#ifdef _SC_GETPW_R_SIZE_MAX
5796 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5797#endif
5798#ifdef _SC_ICACHE_ASSOC
5799 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5800#endif
5801#ifdef _SC_ICACHE_BLKSZ
5802 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5803#endif
5804#ifdef _SC_ICACHE_LINESZ
5805 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5806#endif
5807#ifdef _SC_ICACHE_SZ
5808 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5809#endif
Fred Draked86ed291999-12-15 15:34:33 +00005810#ifdef _SC_INF
5811 {"SC_INF", _SC_INF},
5812#endif
Fred Drakec9680921999-12-13 16:37:25 +00005813#ifdef _SC_INT_MAX
5814 {"SC_INT_MAX", _SC_INT_MAX},
5815#endif
5816#ifdef _SC_INT_MIN
5817 {"SC_INT_MIN", _SC_INT_MIN},
5818#endif
5819#ifdef _SC_IOV_MAX
5820 {"SC_IOV_MAX", _SC_IOV_MAX},
5821#endif
Fred Draked86ed291999-12-15 15:34:33 +00005822#ifdef _SC_IP_SECOPTS
5823 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5824#endif
Fred Drakec9680921999-12-13 16:37:25 +00005825#ifdef _SC_JOB_CONTROL
5826 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5827#endif
Fred Draked86ed291999-12-15 15:34:33 +00005828#ifdef _SC_KERN_POINTERS
5829 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5830#endif
5831#ifdef _SC_KERN_SIM
5832 {"SC_KERN_SIM", _SC_KERN_SIM},
5833#endif
Fred Drakec9680921999-12-13 16:37:25 +00005834#ifdef _SC_LINE_MAX
5835 {"SC_LINE_MAX", _SC_LINE_MAX},
5836#endif
5837#ifdef _SC_LOGIN_NAME_MAX
5838 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5839#endif
5840#ifdef _SC_LOGNAME_MAX
5841 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5842#endif
5843#ifdef _SC_LONG_BIT
5844 {"SC_LONG_BIT", _SC_LONG_BIT},
5845#endif
Fred Draked86ed291999-12-15 15:34:33 +00005846#ifdef _SC_MAC
5847 {"SC_MAC", _SC_MAC},
5848#endif
Fred Drakec9680921999-12-13 16:37:25 +00005849#ifdef _SC_MAPPED_FILES
5850 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5851#endif
5852#ifdef _SC_MAXPID
5853 {"SC_MAXPID", _SC_MAXPID},
5854#endif
5855#ifdef _SC_MB_LEN_MAX
5856 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5857#endif
5858#ifdef _SC_MEMLOCK
5859 {"SC_MEMLOCK", _SC_MEMLOCK},
5860#endif
5861#ifdef _SC_MEMLOCK_RANGE
5862 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5863#endif
5864#ifdef _SC_MEMORY_PROTECTION
5865 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5866#endif
5867#ifdef _SC_MESSAGE_PASSING
5868 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5869#endif
Fred Draked86ed291999-12-15 15:34:33 +00005870#ifdef _SC_MMAP_FIXED_ALIGNMENT
5871 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5872#endif
Fred Drakec9680921999-12-13 16:37:25 +00005873#ifdef _SC_MQ_OPEN_MAX
5874 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5875#endif
5876#ifdef _SC_MQ_PRIO_MAX
5877 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5878#endif
Fred Draked86ed291999-12-15 15:34:33 +00005879#ifdef _SC_NACLS_MAX
5880 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5881#endif
Fred Drakec9680921999-12-13 16:37:25 +00005882#ifdef _SC_NGROUPS_MAX
5883 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5884#endif
5885#ifdef _SC_NL_ARGMAX
5886 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5887#endif
5888#ifdef _SC_NL_LANGMAX
5889 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5890#endif
5891#ifdef _SC_NL_MSGMAX
5892 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5893#endif
5894#ifdef _SC_NL_NMAX
5895 {"SC_NL_NMAX", _SC_NL_NMAX},
5896#endif
5897#ifdef _SC_NL_SETMAX
5898 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5899#endif
5900#ifdef _SC_NL_TEXTMAX
5901 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5902#endif
5903#ifdef _SC_NPROCESSORS_CONF
5904 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5905#endif
5906#ifdef _SC_NPROCESSORS_ONLN
5907 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5908#endif
Fred Draked86ed291999-12-15 15:34:33 +00005909#ifdef _SC_NPROC_CONF
5910 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5911#endif
5912#ifdef _SC_NPROC_ONLN
5913 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5914#endif
Fred Drakec9680921999-12-13 16:37:25 +00005915#ifdef _SC_NZERO
5916 {"SC_NZERO", _SC_NZERO},
5917#endif
5918#ifdef _SC_OPEN_MAX
5919 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5920#endif
5921#ifdef _SC_PAGESIZE
5922 {"SC_PAGESIZE", _SC_PAGESIZE},
5923#endif
5924#ifdef _SC_PAGE_SIZE
5925 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5926#endif
5927#ifdef _SC_PASS_MAX
5928 {"SC_PASS_MAX", _SC_PASS_MAX},
5929#endif
5930#ifdef _SC_PHYS_PAGES
5931 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5932#endif
5933#ifdef _SC_PII
5934 {"SC_PII", _SC_PII},
5935#endif
5936#ifdef _SC_PII_INTERNET
5937 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5938#endif
5939#ifdef _SC_PII_INTERNET_DGRAM
5940 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5941#endif
5942#ifdef _SC_PII_INTERNET_STREAM
5943 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5944#endif
5945#ifdef _SC_PII_OSI
5946 {"SC_PII_OSI", _SC_PII_OSI},
5947#endif
5948#ifdef _SC_PII_OSI_CLTS
5949 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5950#endif
5951#ifdef _SC_PII_OSI_COTS
5952 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5953#endif
5954#ifdef _SC_PII_OSI_M
5955 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5956#endif
5957#ifdef _SC_PII_SOCKET
5958 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5959#endif
5960#ifdef _SC_PII_XTI
5961 {"SC_PII_XTI", _SC_PII_XTI},
5962#endif
5963#ifdef _SC_POLL
5964 {"SC_POLL", _SC_POLL},
5965#endif
5966#ifdef _SC_PRIORITIZED_IO
5967 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5968#endif
5969#ifdef _SC_PRIORITY_SCHEDULING
5970 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5971#endif
5972#ifdef _SC_REALTIME_SIGNALS
5973 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5974#endif
5975#ifdef _SC_RE_DUP_MAX
5976 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5977#endif
5978#ifdef _SC_RTSIG_MAX
5979 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5980#endif
5981#ifdef _SC_SAVED_IDS
5982 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5983#endif
5984#ifdef _SC_SCHAR_MAX
5985 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5986#endif
5987#ifdef _SC_SCHAR_MIN
5988 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5989#endif
5990#ifdef _SC_SELECT
5991 {"SC_SELECT", _SC_SELECT},
5992#endif
5993#ifdef _SC_SEMAPHORES
5994 {"SC_SEMAPHORES", _SC_SEMAPHORES},
5995#endif
5996#ifdef _SC_SEM_NSEMS_MAX
5997 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
5998#endif
5999#ifdef _SC_SEM_VALUE_MAX
6000 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6001#endif
6002#ifdef _SC_SHARED_MEMORY_OBJECTS
6003 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6004#endif
6005#ifdef _SC_SHRT_MAX
6006 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6007#endif
6008#ifdef _SC_SHRT_MIN
6009 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6010#endif
6011#ifdef _SC_SIGQUEUE_MAX
6012 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6013#endif
6014#ifdef _SC_SIGRT_MAX
6015 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6016#endif
6017#ifdef _SC_SIGRT_MIN
6018 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6019#endif
Fred Draked86ed291999-12-15 15:34:33 +00006020#ifdef _SC_SOFTPOWER
6021 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6022#endif
Fred Drakec9680921999-12-13 16:37:25 +00006023#ifdef _SC_SPLIT_CACHE
6024 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6025#endif
6026#ifdef _SC_SSIZE_MAX
6027 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6028#endif
6029#ifdef _SC_STACK_PROT
6030 {"SC_STACK_PROT", _SC_STACK_PROT},
6031#endif
6032#ifdef _SC_STREAM_MAX
6033 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6034#endif
6035#ifdef _SC_SYNCHRONIZED_IO
6036 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6037#endif
6038#ifdef _SC_THREADS
6039 {"SC_THREADS", _SC_THREADS},
6040#endif
6041#ifdef _SC_THREAD_ATTR_STACKADDR
6042 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6043#endif
6044#ifdef _SC_THREAD_ATTR_STACKSIZE
6045 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6046#endif
6047#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6048 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6049#endif
6050#ifdef _SC_THREAD_KEYS_MAX
6051 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6052#endif
6053#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6054 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6055#endif
6056#ifdef _SC_THREAD_PRIO_INHERIT
6057 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6058#endif
6059#ifdef _SC_THREAD_PRIO_PROTECT
6060 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6061#endif
6062#ifdef _SC_THREAD_PROCESS_SHARED
6063 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6064#endif
6065#ifdef _SC_THREAD_SAFE_FUNCTIONS
6066 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6067#endif
6068#ifdef _SC_THREAD_STACK_MIN
6069 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6070#endif
6071#ifdef _SC_THREAD_THREADS_MAX
6072 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6073#endif
6074#ifdef _SC_TIMERS
6075 {"SC_TIMERS", _SC_TIMERS},
6076#endif
6077#ifdef _SC_TIMER_MAX
6078 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6079#endif
6080#ifdef _SC_TTY_NAME_MAX
6081 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6082#endif
6083#ifdef _SC_TZNAME_MAX
6084 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6085#endif
6086#ifdef _SC_T_IOV_MAX
6087 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6088#endif
6089#ifdef _SC_UCHAR_MAX
6090 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6091#endif
6092#ifdef _SC_UINT_MAX
6093 {"SC_UINT_MAX", _SC_UINT_MAX},
6094#endif
6095#ifdef _SC_UIO_MAXIOV
6096 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6097#endif
6098#ifdef _SC_ULONG_MAX
6099 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6100#endif
6101#ifdef _SC_USHRT_MAX
6102 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6103#endif
6104#ifdef _SC_VERSION
6105 {"SC_VERSION", _SC_VERSION},
6106#endif
6107#ifdef _SC_WORD_BIT
6108 {"SC_WORD_BIT", _SC_WORD_BIT},
6109#endif
6110#ifdef _SC_XBS5_ILP32_OFF32
6111 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6112#endif
6113#ifdef _SC_XBS5_ILP32_OFFBIG
6114 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6115#endif
6116#ifdef _SC_XBS5_LP64_OFF64
6117 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6118#endif
6119#ifdef _SC_XBS5_LPBIG_OFFBIG
6120 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6121#endif
6122#ifdef _SC_XOPEN_CRYPT
6123 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6124#endif
6125#ifdef _SC_XOPEN_ENH_I18N
6126 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6127#endif
6128#ifdef _SC_XOPEN_LEGACY
6129 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6130#endif
6131#ifdef _SC_XOPEN_REALTIME
6132 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6133#endif
6134#ifdef _SC_XOPEN_REALTIME_THREADS
6135 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6136#endif
6137#ifdef _SC_XOPEN_SHM
6138 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6139#endif
6140#ifdef _SC_XOPEN_UNIX
6141 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6142#endif
6143#ifdef _SC_XOPEN_VERSION
6144 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6145#endif
6146#ifdef _SC_XOPEN_XCU_VERSION
6147 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6148#endif
6149#ifdef _SC_XOPEN_XPG2
6150 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6151#endif
6152#ifdef _SC_XOPEN_XPG3
6153 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6154#endif
6155#ifdef _SC_XOPEN_XPG4
6156 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6157#endif
6158};
6159
6160static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006161conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006162{
6163 return conv_confname(arg, valuep, posix_constants_sysconf,
6164 sizeof(posix_constants_sysconf)
6165 / sizeof(struct constdef));
6166}
6167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006168PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006169"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006170Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006171
6172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006173posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006174{
6175 PyObject *result = NULL;
6176 int name;
6177
6178 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6179 int value;
6180
6181 errno = 0;
6182 value = sysconf(name);
6183 if (value == -1 && errno != 0)
6184 posix_error();
6185 else
6186 result = PyInt_FromLong(value);
6187 }
6188 return result;
6189}
6190#endif
6191
6192
Fred Drakebec628d1999-12-15 18:31:10 +00006193/* This code is used to ensure that the tables of configuration value names
6194 * are in sorted order as required by conv_confname(), and also to build the
6195 * the exported dictionaries that are used to publish information about the
6196 * names available on the host platform.
6197 *
6198 * Sorting the table at runtime ensures that the table is properly ordered
6199 * when used, even for platforms we're not able to test on. It also makes
6200 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006201 */
Fred Drakebec628d1999-12-15 18:31:10 +00006202
6203static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006204cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006205{
6206 const struct constdef *c1 =
6207 (const struct constdef *) v1;
6208 const struct constdef *c2 =
6209 (const struct constdef *) v2;
6210
6211 return strcmp(c1->name, c2->name);
6212}
6213
6214static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006215setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006216 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006217{
Fred Drakebec628d1999-12-15 18:31:10 +00006218 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006219 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006220
6221 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6222 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006223 if (d == NULL)
6224 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006225
Barry Warsaw3155db32000-04-13 15:20:40 +00006226 for (i=0; i < tablesize; ++i) {
6227 PyObject *o = PyInt_FromLong(table[i].value);
6228 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6229 Py_XDECREF(o);
6230 Py_DECREF(d);
6231 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006232 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006233 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006234 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006235 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006236}
6237
Fred Drakebec628d1999-12-15 18:31:10 +00006238/* Return -1 on failure, 0 on success. */
6239static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006240setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006241{
6242#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006243 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006244 sizeof(posix_constants_pathconf)
6245 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006246 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006247 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006248#endif
6249#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006250 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006251 sizeof(posix_constants_confstr)
6252 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006253 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006254 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006255#endif
6256#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006257 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006258 sizeof(posix_constants_sysconf)
6259 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006260 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006261 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006262#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006263 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006264}
Fred Draked86ed291999-12-15 15:34:33 +00006265
6266
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006267PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006268"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006269Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006270in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006271
6272static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006273posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006274{
6275 if (!PyArg_ParseTuple(args, ":abort"))
6276 return NULL;
6277 abort();
6278 /*NOTREACHED*/
6279 Py_FatalError("abort() called from Python code didn't abort!");
6280 return NULL;
6281}
Fred Drakebec628d1999-12-15 18:31:10 +00006282
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006283#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006284PyDoc_STRVAR(win32_startfile__doc__,
6285"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006286\n\
6287This acts like double-clicking the file in Explorer, or giving the file\n\
6288name as an argument to the DOS \"start\" command: the file is opened\n\
6289with whatever application (if any) its extension is associated.\n\
6290\n\
6291startfile returns as soon as the associated application is launched.\n\
6292There is no option to wait for the application to close, and no way\n\
6293to retrieve the application's exit status.\n\
6294\n\
6295The filepath is relative to the current directory. If you want to use\n\
6296an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006297the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006298
6299static PyObject *
6300win32_startfile(PyObject *self, PyObject *args)
6301{
6302 char *filepath;
6303 HINSTANCE rc;
6304 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6305 return NULL;
6306 Py_BEGIN_ALLOW_THREADS
6307 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6308 Py_END_ALLOW_THREADS
6309 if (rc <= (HINSTANCE)32)
6310 return win32_error("startfile", filepath);
6311 Py_INCREF(Py_None);
6312 return Py_None;
6313}
6314#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006315
6316static PyMethodDef posix_methods[] = {
6317 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6318#ifdef HAVE_TTYNAME
6319 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6320#endif
6321 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6322 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006323#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006324 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006325#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006326#ifdef HAVE_LCHOWN
6327 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6328#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006329#ifdef HAVE_CHROOT
6330 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6331#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006332#ifdef HAVE_CTERMID
6333 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6334#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006335#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006336 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006337#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006338#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006339 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006340#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006341 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6342 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6343 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006344#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006345 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006346#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006347#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006348 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006349#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006350 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6351 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6352 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006353#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006354 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006355#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006356#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006357 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006358#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006359 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006360#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006361 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006362#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006363 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6364 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6365 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006366#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006367 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006368#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006369 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006370#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006371 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6372 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006373#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006374#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006375 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6376 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006377#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006378#ifdef HAVE_FORK1
6379 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6380#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006381#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006382 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006383#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006384#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006385 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006386#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006387#ifdef HAVE_FORKPTY
6388 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6389#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006390#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006391 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006392#endif /* HAVE_GETEGID */
6393#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006394 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006395#endif /* HAVE_GETEUID */
6396#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006397 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006398#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006399#ifdef HAVE_GETGROUPS
6400 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6401#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006402 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006403#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006404 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006405#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006406#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006407 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006408#endif /* HAVE_GETPPID */
6409#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006410 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006411#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006412#ifdef HAVE_GETLOGIN
6413 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6414#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006415#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006416 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006417#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006418#ifdef HAVE_KILLPG
6419 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6420#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006421#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006422 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006423#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006424#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006425 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006426#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006427 {"popen2", win32_popen2, METH_VARARGS},
6428 {"popen3", win32_popen3, METH_VARARGS},
6429 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006430 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006431#else
6432#if defined(PYOS_OS2) && defined(PYCC_GCC)
6433 {"popen2", os2emx_popen2, METH_VARARGS},
6434 {"popen3", os2emx_popen3, METH_VARARGS},
6435 {"popen4", os2emx_popen4, METH_VARARGS},
6436#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006437#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006438#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006439#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006440 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006441#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006442#ifdef HAVE_SETEUID
6443 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6444#endif /* HAVE_SETEUID */
6445#ifdef HAVE_SETEGID
6446 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6447#endif /* HAVE_SETEGID */
6448#ifdef HAVE_SETREUID
6449 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6450#endif /* HAVE_SETREUID */
6451#ifdef HAVE_SETREGID
6452 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6453#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006454#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006455 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006456#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006457#ifdef HAVE_SETGROUPS
6458 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6459#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006460#ifdef HAVE_GETPGID
6461 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6462#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006463#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006464 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006465#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006466#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006467 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006468#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006469#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006470 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006471#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006472#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006473 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006474#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006475#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006476 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006477#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006478#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006479 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006480#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006481#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006482 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006483#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006484 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6485 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6486 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6487 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6488 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6489 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6490 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6491 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6492 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006493 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006494#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006495 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006496#endif
6497#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006498 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006499#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006500#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006501 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6502#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006503#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006504 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006505#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006506#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006507 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006508#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006509#ifdef HAVE_UNSETENV
6510 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6511#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006512#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006513 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006514#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006515#ifdef HAVE_FCHDIR
6516 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6517#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006518#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006519 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006520#endif
6521#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006522 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006523#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006524#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006525#ifdef WCOREDUMP
6526 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6527#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006528#ifdef WIFCONTINUED
6529 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6530#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006531#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006532 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006533#endif /* WIFSTOPPED */
6534#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006535 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006536#endif /* WIFSIGNALED */
6537#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006538 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006539#endif /* WIFEXITED */
6540#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006541 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006542#endif /* WEXITSTATUS */
6543#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006544 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006545#endif /* WTERMSIG */
6546#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006547 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006548#endif /* WSTOPSIG */
6549#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006550#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006551 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006552#endif
6553#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006554 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006555#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006556#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006557 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6558#endif
6559#ifdef HAVE_TEMPNAM
6560 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6561#endif
6562#ifdef HAVE_TMPNAM
6563 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6564#endif
Fred Drakec9680921999-12-13 16:37:25 +00006565#ifdef HAVE_CONFSTR
6566 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6567#endif
6568#ifdef HAVE_SYSCONF
6569 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6570#endif
6571#ifdef HAVE_FPATHCONF
6572 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6573#endif
6574#ifdef HAVE_PATHCONF
6575 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6576#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006577 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006578#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006579 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6580#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006581 {NULL, NULL} /* Sentinel */
6582};
6583
6584
Barry Warsaw4a342091996-12-19 23:50:02 +00006585static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006586ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006587{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006588 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006589}
6590
Guido van Rossumd48f2521997-12-05 22:19:34 +00006591#if defined(PYOS_OS2)
6592/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006593static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006594{
6595 APIRET rc;
6596 ULONG values[QSV_MAX+1];
6597 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006598 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006599
6600 Py_BEGIN_ALLOW_THREADS
6601 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6602 Py_END_ALLOW_THREADS
6603
6604 if (rc != NO_ERROR) {
6605 os2_error(rc);
6606 return -1;
6607 }
6608
Fred Drake4d1e64b2002-04-15 19:40:07 +00006609 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6610 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6611 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6612 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6613 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6614 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6615 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006616
6617 switch (values[QSV_VERSION_MINOR]) {
6618 case 0: ver = "2.00"; break;
6619 case 10: ver = "2.10"; break;
6620 case 11: ver = "2.11"; break;
6621 case 30: ver = "3.00"; break;
6622 case 40: ver = "4.00"; break;
6623 case 50: ver = "5.00"; break;
6624 default:
Tim Peters885d4572001-11-28 20:27:42 +00006625 PyOS_snprintf(tmp, sizeof(tmp),
6626 "%d-%d", values[QSV_VERSION_MAJOR],
6627 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006628 ver = &tmp[0];
6629 }
6630
6631 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006632 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006633 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006634
6635 /* Add Indicator of Which Drive was Used to Boot the System */
6636 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6637 tmp[1] = ':';
6638 tmp[2] = '\0';
6639
Fred Drake4d1e64b2002-04-15 19:40:07 +00006640 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006641}
6642#endif
6643
Barry Warsaw4a342091996-12-19 23:50:02 +00006644static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006645all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006646{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006647#ifdef F_OK
6648 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006649#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006650#ifdef R_OK
6651 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006652#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006653#ifdef W_OK
6654 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006655#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006656#ifdef X_OK
6657 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006658#endif
Fred Drakec9680921999-12-13 16:37:25 +00006659#ifdef NGROUPS_MAX
6660 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6661#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006662#ifdef TMP_MAX
6663 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6664#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006665#ifdef WCONTINUED
6666 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6667#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006668#ifdef WNOHANG
6669 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006670#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006671#ifdef WUNTRACED
6672 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6673#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006674#ifdef O_RDONLY
6675 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6676#endif
6677#ifdef O_WRONLY
6678 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6679#endif
6680#ifdef O_RDWR
6681 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6682#endif
6683#ifdef O_NDELAY
6684 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6685#endif
6686#ifdef O_NONBLOCK
6687 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6688#endif
6689#ifdef O_APPEND
6690 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6691#endif
6692#ifdef O_DSYNC
6693 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6694#endif
6695#ifdef O_RSYNC
6696 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6697#endif
6698#ifdef O_SYNC
6699 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6700#endif
6701#ifdef O_NOCTTY
6702 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6703#endif
6704#ifdef O_CREAT
6705 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6706#endif
6707#ifdef O_EXCL
6708 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6709#endif
6710#ifdef O_TRUNC
6711 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6712#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006713#ifdef O_BINARY
6714 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6715#endif
6716#ifdef O_TEXT
6717 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6718#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006719#ifdef O_LARGEFILE
6720 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6721#endif
6722
Tim Peters5aa91602002-01-30 05:46:57 +00006723/* MS Windows */
6724#ifdef O_NOINHERIT
6725 /* Don't inherit in child processes. */
6726 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6727#endif
6728#ifdef _O_SHORT_LIVED
6729 /* Optimize for short life (keep in memory). */
6730 /* MS forgot to define this one with a non-underscore form too. */
6731 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6732#endif
6733#ifdef O_TEMPORARY
6734 /* Automatically delete when last handle is closed. */
6735 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6736#endif
6737#ifdef O_RANDOM
6738 /* Optimize for random access. */
6739 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6740#endif
6741#ifdef O_SEQUENTIAL
6742 /* Optimize for sequential access. */
6743 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6744#endif
6745
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006746/* GNU extensions. */
6747#ifdef O_DIRECT
6748 /* Direct disk access. */
6749 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6750#endif
6751#ifdef O_DIRECTORY
6752 /* Must be a directory. */
6753 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6754#endif
6755#ifdef O_NOFOLLOW
6756 /* Do not follow links. */
6757 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6758#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006759
Guido van Rossum246bc171999-02-01 23:54:31 +00006760#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006761#if defined(PYOS_OS2) && defined(PYCC_GCC)
6762 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6763 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6764 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6765 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6766 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6767 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6768 if (ins(d, "P_PM", (long)P_PM)) return -1;
6769 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6770 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6771 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6772 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6773 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6774 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6775 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6776 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6777 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6778 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6779 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6780 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6781 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6782#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006783 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6784 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6785 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6786 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6787 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006788#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006789#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006790
Guido van Rossumd48f2521997-12-05 22:19:34 +00006791#if defined(PYOS_OS2)
6792 if (insertvalues(d)) return -1;
6793#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006794 return 0;
6795}
6796
6797
Tim Peters5aa91602002-01-30 05:46:57 +00006798#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006799#define INITFUNC initnt
6800#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006801
6802#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006803#define INITFUNC initos2
6804#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006805
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006806#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006807#define INITFUNC initposix
6808#define MODNAME "posix"
6809#endif
6810
Mark Hammondfe51c6d2002-08-02 02:27:13 +00006811PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006812INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006813{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006814 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006815
Fred Drake4d1e64b2002-04-15 19:40:07 +00006816 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006817 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006818 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006819
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006820 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006821 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006822 Py_XINCREF(v);
6823 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006824 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006825 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006826
Fred Drake4d1e64b2002-04-15 19:40:07 +00006827 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006828 return;
6829
Fred Drake4d1e64b2002-04-15 19:40:07 +00006830 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006831 return;
6832
Fred Drake4d1e64b2002-04-15 19:40:07 +00006833 Py_INCREF(PyExc_OSError);
6834 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006835
Guido van Rossumb3d39562000-01-31 18:41:26 +00006836#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006837 if (posix_putenv_garbage == NULL)
6838 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006839#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006840
Guido van Rossum14648392001-12-08 18:02:58 +00006841 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006842 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006843 Py_INCREF((PyObject*) &StatResultType);
6844 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006845
Guido van Rossum14648392001-12-08 18:02:58 +00006846 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006847 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006848 Py_INCREF((PyObject*) &StatVFSResultType);
6849 PyModule_AddObject(m, "statvfs_result",
6850 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006851}