blob: 9ac0eb4993e24df4cdb01e81f4a0947e6cd5773f [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
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000132#if defined(__sgi)&&_COMPILER_VERSION>=700
133/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
134 (default) */
135extern char *ctermid_r(char *);
136#endif
137
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000138#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000140extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000141#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000143extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int chdir(char *);
150extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000151#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int chdir(const char *);
153extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000154#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000155#ifdef __BORLANDC__
156extern int chmod(const char *, int);
157#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000159#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int chown(const char *, uid_t, gid_t);
161extern char *getcwd(char *, int);
162extern char *strerror(int);
163extern int link(const char *, const char *);
164extern int rename(const char *, const char *);
165extern int stat(const char *, struct stat *);
166extern int unlink(const char *);
167extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000170#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000171#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000173#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000175
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000176#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178#ifdef HAVE_UTIME_H
179#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000180#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000182#ifdef HAVE_SYS_UTIME_H
183#include <sys/utime.h>
184#define HAVE_UTIME_H /* pretend we do for the rest of this file */
185#endif /* HAVE_SYS_UTIME_H */
186
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187#ifdef HAVE_SYS_TIMES_H
188#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
191#ifdef HAVE_SYS_PARAM_H
192#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000193#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000194
195#ifdef HAVE_SYS_UTSNAME_H
196#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000199#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000200#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000201#define NAMLEN(dirent) strlen((dirent)->d_name)
202#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000203#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000204#include <direct.h>
205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#endif
213#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#endif
216#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000218#endif
219#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000221#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <direct.h>
223#include <io.h>
224#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000225#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000226#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000228#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000229#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000230#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000231#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossumd48f2521997-12-05 22:19:34 +0000233#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000235#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236
Tim Petersbc2e10e2002-03-03 23:17:02 +0000237#ifndef MAXPATHLEN
238#define MAXPATHLEN 1024
239#endif /* MAXPATHLEN */
240
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000241#ifdef UNION_WAIT
242/* Emulate some macros on systems that have a union instead of macros */
243
244#ifndef WIFEXITED
245#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
246#endif
247
248#ifndef WEXITSTATUS
249#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
250#endif
251
252#ifndef WTERMSIG
253#define WTERMSIG(u_wait) ((u_wait).w_termsig)
254#endif
255
256#endif /* UNION_WAIT */
257
Greg Wardb48bc172000-03-01 21:51:56 +0000258/* Don't use the "_r" form if we don't need it (also, won't have a
259 prototype for it, at least on Solaris -- maybe others as well?). */
260#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
261#define USE_CTERMID_R
262#endif
263
264#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
265#define USE_TMPNAM_R
266#endif
267
Fred Drake699f3522000-06-29 21:12:41 +0000268/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000269#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000270#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000271# define STAT _stati64
272# define FSTAT _fstati64
273# define STRUCT_STAT struct _stati64
274#else
275# define STAT stat
276# define FSTAT fstat
277# define STRUCT_STAT struct stat
278#endif
279
Neal Norwitz3d949422002-04-20 13:46:43 +0000280#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
281#include <sys/mkdev.h>
282#endif
Fred Drake699f3522000-06-29 21:12:41 +0000283
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000285#ifdef WITH_NEXT_FRAMEWORK
286/* On Darwin/MacOSX a shared library or framework has no access to
287** environ directly, we must obtain it with _NSGetEnviron().
288*/
289#include <crt_externs.h>
290static char **environ;
291#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000293#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294
Barry Warsaw53699e91996-12-10 23:23:01 +0000295static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000296convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297{
Barry Warsaw53699e91996-12-10 23:23:01 +0000298 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000300 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301 if (d == NULL)
302 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000303#ifdef WITH_NEXT_FRAMEWORK
304 if (environ == NULL)
305 environ = *_NSGetEnviron();
306#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000307 if (environ == NULL)
308 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000309 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000311 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000312 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 char *p = strchr(*e, '=');
314 if (p == NULL)
315 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000316 k = PyString_FromStringAndSize(*e, (int)(p-*e));
317 if (k == NULL) {
318 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000320 }
321 v = PyString_FromString(p+1);
322 if (v == NULL) {
323 PyErr_Clear();
324 Py_DECREF(k);
325 continue;
326 }
327 if (PyDict_GetItem(d, k) == NULL) {
328 if (PyDict_SetItem(d, k, v) != 0)
329 PyErr_Clear();
330 }
331 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000332 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000334#if defined(PYOS_OS2)
335 {
336 APIRET rc;
337 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
338
339 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000340 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000341 PyObject *v = PyString_FromString(buffer);
342 PyDict_SetItemString(d, "BEGINLIBPATH", v);
343 Py_DECREF(v);
344 }
345 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
346 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
347 PyObject *v = PyString_FromString(buffer);
348 PyDict_SetItemString(d, "ENDLIBPATH", v);
349 Py_DECREF(v);
350 }
351 }
352#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000353 return d;
354}
355
356
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357/* Set a POSIX-specific error from errno, and return NULL */
358
Barry Warsawd58d7641998-07-23 16:14:40 +0000359static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000360posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000361{
Barry Warsawca74da41999-02-09 19:31:45 +0000362 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363}
Barry Warsawd58d7641998-07-23 16:14:40 +0000364static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000365posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000366{
Barry Warsawca74da41999-02-09 19:31:45 +0000367 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000368}
369
Mark Hammondef8b6542001-05-13 08:04:26 +0000370static PyObject *
371posix_error_with_allocated_filename(char* name)
372{
373 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
374 PyMem_Free(name);
375 return rc;
376}
377
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000378#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000379static PyObject *
380win32_error(char* function, char* filename)
381{
Mark Hammond33a6da92000-08-15 00:46:38 +0000382 /* XXX We should pass the function name along in the future.
383 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000384 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000385 Windows error object, which is non-trivial.
386 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000387 errno = GetLastError();
388 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000389 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000390 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000391 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000392}
393#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000394
Guido van Rossumd48f2521997-12-05 22:19:34 +0000395#if defined(PYOS_OS2)
396/**********************************************************************
397 * Helper Function to Trim and Format OS/2 Messages
398 **********************************************************************/
399 static void
400os2_formatmsg(char *msgbuf, int msglen, char *reason)
401{
402 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
403
404 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
405 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
406
407 while (lastc > msgbuf && isspace(*lastc))
408 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
409 }
410
411 /* Add Optional Reason Text */
412 if (reason) {
413 strcat(msgbuf, " : ");
414 strcat(msgbuf, reason);
415 }
416}
417
418/**********************************************************************
419 * Decode an OS/2 Operating System Error Code
420 *
421 * A convenience function to lookup an OS/2 error code and return a
422 * text message we can use to raise a Python exception.
423 *
424 * Notes:
425 * The messages for errors returned from the OS/2 kernel reside in
426 * the file OSO001.MSG in the \OS2 directory hierarchy.
427 *
428 **********************************************************************/
429 static char *
430os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
431{
432 APIRET rc;
433 ULONG msglen;
434
435 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
436 Py_BEGIN_ALLOW_THREADS
437 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
438 errorcode, "oso001.msg", &msglen);
439 Py_END_ALLOW_THREADS
440
441 if (rc == NO_ERROR)
442 os2_formatmsg(msgbuf, msglen, reason);
443 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000444 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000445 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000446
447 return msgbuf;
448}
449
450/* Set an OS/2-specific error and return NULL. OS/2 kernel
451 errors are not in a global variable e.g. 'errno' nor are
452 they congruent with posix error numbers. */
453
454static PyObject * os2_error(int code)
455{
456 char text[1024];
457 PyObject *v;
458
459 os2_strerror(text, sizeof(text), code, "");
460
461 v = Py_BuildValue("(is)", code, text);
462 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000463 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000464 Py_DECREF(v);
465 }
466 return NULL; /* Signal to Python that an Exception is Pending */
467}
468
469#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000470
471/* POSIX generic methods */
472
Barry Warsaw53699e91996-12-10 23:23:01 +0000473static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000474posix_fildes(PyObject *fdobj, int (*func)(int))
475{
476 int fd;
477 int res;
478 fd = PyObject_AsFileDescriptor(fdobj);
479 if (fd < 0)
480 return NULL;
481 Py_BEGIN_ALLOW_THREADS
482 res = (*func)(fd);
483 Py_END_ALLOW_THREADS
484 if (res < 0)
485 return posix_error();
486 Py_INCREF(Py_None);
487 return Py_None;
488}
Guido van Rossum21142a01999-01-08 21:05:37 +0000489
490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000491posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000492{
Mark Hammondef8b6542001-05-13 08:04:26 +0000493 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000494 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000495 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000496 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000497 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000498 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000499 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000500 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000501 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000502 return posix_error_with_allocated_filename(path1);
503 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000504 Py_INCREF(Py_None);
505 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000506}
507
Barry Warsaw53699e91996-12-10 23:23:01 +0000508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000509posix_2str(PyObject *args, char *format,
510 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000511{
Mark Hammondef8b6542001-05-13 08:04:26 +0000512 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000513 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000514 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000515 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000516 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000517 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000518 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000519 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000520 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000521 PyMem_Free(path1);
522 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000523 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000524 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000526 Py_INCREF(Py_None);
527 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000528}
529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000530PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000531"stat_result: Result from stat or lstat.\n\n\
532This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000533 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000534or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
535\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000536Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000537they are available as attributes only.\n\
538\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000539See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000540
541static PyStructSequence_Field stat_result_fields[] = {
542 {"st_mode", "protection bits"},
543 {"st_ino", "inode"},
544 {"st_dev", "device"},
545 {"st_nlink", "number of hard links"},
546 {"st_uid", "user ID of owner"},
547 {"st_gid", "group ID of owner"},
548 {"st_size", "total size, in bytes"},
549 {"st_atime", "time of last access"},
550 {"st_mtime", "time of last modification"},
551 {"st_ctime", "time of last change"},
552#ifdef HAVE_ST_BLKSIZE
553 {"st_blksize", "blocksize for filesystem I/O"},
554#endif
555#ifdef HAVE_ST_BLOCKS
556 {"st_blocks", "number of blocks allocated"},
557#endif
558#ifdef HAVE_ST_RDEV
559 {"st_rdev", "device type (if inode device)"},
560#endif
561 {0}
562};
563
564#ifdef HAVE_ST_BLKSIZE
565#define ST_BLKSIZE_IDX 10
566#else
567#define ST_BLKSIZE_IDX 9
568#endif
569
570#ifdef HAVE_ST_BLOCKS
571#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
572#else
573#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
574#endif
575
576#ifdef HAVE_ST_RDEV
577#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
578#else
579#define ST_RDEV_IDX ST_BLOCKS_IDX
580#endif
581
582static PyStructSequence_Desc stat_result_desc = {
583 "stat_result", /* name */
584 stat_result__doc__, /* doc */
585 stat_result_fields,
586 10
587};
588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000589PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000590"statvfs_result: Result from statvfs or fstatvfs.\n\n\
591This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000592 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000593or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000594\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000595See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000596
597static PyStructSequence_Field statvfs_result_fields[] = {
598 {"f_bsize", },
599 {"f_frsize", },
600 {"f_blocks", },
601 {"f_bfree", },
602 {"f_bavail", },
603 {"f_files", },
604 {"f_ffree", },
605 {"f_favail", },
606 {"f_flag", },
607 {"f_namemax",},
608 {0}
609};
610
611static PyStructSequence_Desc statvfs_result_desc = {
612 "statvfs_result", /* name */
613 statvfs_result__doc__, /* doc */
614 statvfs_result_fields,
615 10
616};
617
618static PyTypeObject StatResultType;
619static PyTypeObject StatVFSResultType;
620
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000621static void
622fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
623{
624 PyObject *val;
Martin v. Löwisa32c9942002-09-09 16:17:47 +0000625 val = PyFloat_FromDouble(sec + 1e-9*nsec);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000626 PyStructSequence_SET_ITEM(v, index, val);
627}
628
Tim Peters5aa91602002-01-30 05:46:57 +0000629/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000630 (used by posix_stat() and posix_fstat()) */
631static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000632_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000633{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000634 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000635 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000636 if (v == NULL)
637 return NULL;
638
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000639 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000640#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000641 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000642 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000643#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000644 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000645#endif
646#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000647 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000648 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000649#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000650 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000651#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000652 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
653 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
654 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000655#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000656 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000657 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000658#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000659 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000660#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000661
662#ifdef HAVE_STAT_TV_NSEC
663 ansec = st.st_atim.tv_nsec;
664 mnsec = st.st_mtim.tv_nsec;
665 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000666#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000667 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000668#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000669 fill_time(v, 7, st.st_atime, ansec);
670 fill_time(v, 8, st.st_mtime, mnsec);
671 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000672
673#ifdef HAVE_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000674 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000675 PyInt_FromLong((long)st.st_blksize));
676#endif
677#ifdef HAVE_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000678 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000679 PyInt_FromLong((long)st.st_blocks));
680#endif
681#ifdef HAVE_ST_RDEV
682 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
683 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000684#endif
685
686 if (PyErr_Occurred()) {
687 Py_DECREF(v);
688 return NULL;
689 }
690
691 return v;
692}
693
Barry Warsaw53699e91996-12-10 23:23:01 +0000694static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000695posix_do_stat(PyObject *self, PyObject *args, char *format,
696 int (*statfunc)(const char *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000697{
Fred Drake699f3522000-06-29 21:12:41 +0000698 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000699 char *path = NULL; /* pass this to stat; do not free() it */
700 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000701 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000702
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000703#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000704 int pathlen;
705 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000706#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000707
Tim Peters5aa91602002-01-30 05:46:57 +0000708 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000709 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000710 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000711 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000712
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000713#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000714 pathlen = strlen(path);
715 /* the library call can blow up if the file name is too long! */
716 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000717 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000718 errno = ENAMETOOLONG;
719 return posix_error();
720 }
721
Tim Peters500bd032001-12-19 19:05:01 +0000722 /* Remove trailing slash or backslash, unless it's the current
723 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
724 */
725 if (pathlen > 0 &&
726 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
727 /* It does end with a slash -- exempt the root drive cases. */
728 /* XXX UNC root drives should also be exempted? */
729 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
730 /* leave it alone */;
731 else {
732 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000733 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000734 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000735 path = pathcopy;
736 }
737 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000738#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000739
Barry Warsaw53699e91996-12-10 23:23:01 +0000740 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000741 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000742 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000743 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000744 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000745
Tim Peters500bd032001-12-19 19:05:01 +0000746 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000747 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000748}
749
750
751/* POSIX methods */
752
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000753PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000754"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000755Use the real uid/gid to test for access to a path. Note that most\n\
756operations will use the effective uid/gid, therefore this routine can\n\
757be used in a suid/sgid environment to test if the invoking user has the\n\
758specified access to the path. The mode argument can be F_OK to test\n\
759existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000760
761static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000762posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000763{
Guido van Rossum015f22a1999-01-06 22:52:38 +0000764 char *path;
765 int mode;
766 int res;
767
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000768 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +0000769 return NULL;
770 Py_BEGIN_ALLOW_THREADS
771 res = access(path, mode);
772 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +0000773 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +0000774}
775
Guido van Rossumd371ff11999-01-25 16:12:23 +0000776#ifndef F_OK
777#define F_OK 0
778#endif
779#ifndef R_OK
780#define R_OK 4
781#endif
782#ifndef W_OK
783#define W_OK 2
784#endif
785#ifndef X_OK
786#define X_OK 1
787#endif
788
789#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000790PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000791"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000792Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +0000793
794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000795posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +0000796{
Guido van Rossum94f6f721999-01-06 18:42:14 +0000797 int id;
798 char *ret;
799
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000800 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +0000801 return NULL;
802
Guido van Rossum94f6f721999-01-06 18:42:14 +0000803 ret = ttyname(id);
804 if (ret == NULL)
805 return(posix_error());
806 return(PyString_FromString(ret));
807}
Guido van Rossumd371ff11999-01-25 16:12:23 +0000808#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +0000809
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000810#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000811PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000812"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000813Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000814
815static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000816posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000817{
818 char *ret;
819 char buffer[L_ctermid];
820
821 if (!PyArg_ParseTuple(args, ":ctermid"))
822 return NULL;
823
Greg Wardb48bc172000-03-01 21:51:56 +0000824#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000825 ret = ctermid_r(buffer);
826#else
827 ret = ctermid(buffer);
828#endif
829 if (ret == NULL)
830 return(posix_error());
831 return(PyString_FromString(buffer));
832}
833#endif
834
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000835PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000836"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000837Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000838
Barry Warsaw53699e91996-12-10 23:23:01 +0000839static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000840posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000841{
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000842#if defined(PYOS_OS2) && defined(PYCC_GCC)
843 return posix_1str(args, "et:chdir", _chdir2);
844#else
Mark Hammondef8b6542001-05-13 08:04:26 +0000845 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000846#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000847}
848
Fred Drake4d1e64b2002-04-15 19:40:07 +0000849#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000850PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000851"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +0000852Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000853opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +0000854
855static PyObject *
856posix_fchdir(PyObject *self, PyObject *fdobj)
857{
858 return posix_fildes(fdobj, fchdir);
859}
860#endif /* HAVE_FCHDIR */
861
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000863PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000864"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000865Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000866
Barry Warsaw53699e91996-12-10 23:23:01 +0000867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000868posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000869{
Mark Hammondef8b6542001-05-13 08:04:26 +0000870 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +0000871 int i;
872 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000873 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +0000874 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +0000875 return NULL;
876 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +0000877 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000878 Py_END_ALLOW_THREADS
879 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000880 return posix_error_with_allocated_filename(path);
881 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +0000882 Py_INCREF(Py_None);
883 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000884}
885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000886
Martin v. Löwis244edc82001-10-04 22:44:26 +0000887#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000888PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000889"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000890Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +0000891
892static PyObject *
893posix_chroot(PyObject *self, PyObject *args)
894{
895 return posix_1str(args, "et:chroot", chroot);
896}
897#endif
898
Guido van Rossum21142a01999-01-08 21:05:37 +0000899#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000900PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000901"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000902force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000903
904static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000905posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000906{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000907 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000908}
909#endif /* HAVE_FSYNC */
910
911#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +0000912
Guido van Rossum7f58e2e2000-09-22 17:26:14 +0000913#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +0000914extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
915#endif
916
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000917PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000918"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +0000919force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000920 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +0000921
922static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000923posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +0000924{
Fred Drake4d1e64b2002-04-15 19:40:07 +0000925 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +0000926}
927#endif /* HAVE_FDATASYNC */
928
929
Fredrik Lundh10723342000-07-10 16:38:09 +0000930#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000931PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000932"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000933Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000934
Barry Warsaw53699e91996-12-10 23:23:01 +0000935static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000936posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000937{
Mark Hammondef8b6542001-05-13 08:04:26 +0000938 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +0000939 int uid, gid;
940 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000941 if (!PyArg_ParseTuple(args, "etii:chown",
942 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +0000943 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +0000944 return NULL;
945 Py_BEGIN_ALLOW_THREADS
946 res = chown(path, (uid_t) uid, (gid_t) gid);
947 Py_END_ALLOW_THREADS
948 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000949 return posix_error_with_allocated_filename(path);
950 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +0000951 Py_INCREF(Py_None);
952 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000953}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000954#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000955
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +0000956#ifdef HAVE_LCHOWN
957PyDoc_STRVAR(posix_lchown__doc__,
958"lchown(path, uid, gid)\n\n\
959Change the owner and group id of path to the numeric uid and gid.\n\
960This function will not follow symbolic links.");
961
962static PyObject *
963posix_lchown(PyObject *self, PyObject *args)
964{
965 char *path = NULL;
966 int uid, gid;
967 int res;
968 if (!PyArg_ParseTuple(args, "etii:lchown",
969 Py_FileSystemDefaultEncoding, &path,
970 &uid, &gid))
971 return NULL;
972 Py_BEGIN_ALLOW_THREADS
973 res = lchown(path, (uid_t) uid, (gid_t) gid);
974 Py_END_ALLOW_THREADS
975 if (res < 0)
976 return posix_error_with_allocated_filename(path);
977 PyMem_Free(path);
978 Py_INCREF(Py_None);
979 return Py_None;
980}
981#endif /* HAVE_LCHOWN */
982
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000983
Guido van Rossum36bc6801995-06-14 22:54:23 +0000984#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000985PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000986"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000987Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +0000988
Barry Warsaw53699e91996-12-10 23:23:01 +0000989static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000990posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000991{
992 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +0000993 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +0000994 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000995 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000996 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000997#if defined(PYOS_OS2) && defined(PYCC_GCC)
998 res = _getcwd2(buf, sizeof buf);
999#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001000 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001001#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001002 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001003 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001004 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001005 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001006}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001007#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001009
Guido van Rossumb6775db1994-08-01 11:34:53 +00001010#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001011PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001012"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001013Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001014
Barry Warsaw53699e91996-12-10 23:23:01 +00001015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001016posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001017{
Mark Hammondef8b6542001-05-13 08:04:26 +00001018 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001019}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001020#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001022
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001023PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001024"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001025Return a list containing the names of the entries in the directory.\n\
1026\n\
1027 path: path of directory to list\n\
1028\n\
1029The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001030entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001031
Barry Warsaw53699e91996-12-10 23:23:01 +00001032static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001033posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001034{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001035 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001036 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001037#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001038
Barry Warsaw53699e91996-12-10 23:23:01 +00001039 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001040 HANDLE hFindFile;
1041 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001042 /* MAX_PATH characters could mean a bigger encoded string */
1043 char namebuf[MAX_PATH*2+5];
1044 char *bufptr = namebuf;
1045 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001046
Tim Peters5aa91602002-01-30 05:46:57 +00001047 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001048 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001049 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001050 if (len > 0) {
1051 char ch = namebuf[len-1];
1052 if (ch != SEP && ch != ALTSEP && ch != ':')
1053 namebuf[len++] = '/';
1054 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001055 strcpy(namebuf + len, "*.*");
1056
Barry Warsaw53699e91996-12-10 23:23:01 +00001057 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001058 return NULL;
1059
1060 hFindFile = FindFirstFile(namebuf, &FileData);
1061 if (hFindFile == INVALID_HANDLE_VALUE) {
1062 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001063 if (errno == ERROR_FILE_NOT_FOUND)
1064 return PyList_New(0);
Mark Hammondef8b6542001-05-13 08:04:26 +00001065 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001066 }
1067 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001068 if (FileData.cFileName[0] == '.' &&
1069 (FileData.cFileName[1] == '\0' ||
1070 FileData.cFileName[1] == '.' &&
1071 FileData.cFileName[2] == '\0'))
1072 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001073 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001074 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001075 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 if (PyList_Append(d, v) != 0) {
1080 Py_DECREF(v);
1081 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001082 d = NULL;
1083 break;
1084 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001085 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001086 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1087
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001088 if (FindClose(hFindFile) == FALSE)
Mark Hammondef8b6542001-05-13 08:04:26 +00001089 return win32_error("FindClose", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001090
1091 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001092
Tim Peters0bb44a42000-09-15 07:44:49 +00001093#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001094
1095#ifndef MAX_PATH
1096#define MAX_PATH CCHMAXPATH
1097#endif
1098 char *name, *pt;
1099 int len;
1100 PyObject *d, *v;
1101 char namebuf[MAX_PATH+5];
1102 HDIR hdir = 1;
1103 ULONG srchcnt = 1;
1104 FILEFINDBUF3 ep;
1105 APIRET rc;
1106
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001107 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001108 return NULL;
1109 if (len >= MAX_PATH) {
1110 PyErr_SetString(PyExc_ValueError, "path too long");
1111 return NULL;
1112 }
1113 strcpy(namebuf, name);
1114 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001115 if (*pt == ALTSEP)
1116 *pt = SEP;
1117 if (namebuf[len-1] != SEP)
1118 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001119 strcpy(namebuf + len, "*.*");
1120
1121 if ((d = PyList_New(0)) == NULL)
1122 return NULL;
1123
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001124 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1125 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001126 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001127 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1128 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1129 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001130
1131 if (rc != NO_ERROR) {
1132 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001133 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001134 }
1135
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001136 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001137 do {
1138 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001139 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001140 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001141
1142 strcpy(namebuf, ep.achName);
1143
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001144 /* Leave Case of Name Alone -- In Native Form */
1145 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001146
1147 v = PyString_FromString(namebuf);
1148 if (v == NULL) {
1149 Py_DECREF(d);
1150 d = NULL;
1151 break;
1152 }
1153 if (PyList_Append(d, v) != 0) {
1154 Py_DECREF(v);
1155 Py_DECREF(d);
1156 d = NULL;
1157 break;
1158 }
1159 Py_DECREF(v);
1160 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1161 }
1162
1163 return d;
1164#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001165
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001166 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001167 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001169 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001170 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001172 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001173 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001174 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001175 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001176 closedir(dirp);
1177 return NULL;
1178 }
1179 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001180 if (ep->d_name[0] == '.' &&
1181 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001182 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001183 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001184 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001185 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001186 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 if (PyList_Append(d, v) != 0) {
1191 Py_DECREF(v);
1192 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001193 d = NULL;
1194 break;
1195 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001196 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001197 }
1198 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001199
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001200 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001201
Tim Peters0bb44a42000-09-15 07:44:49 +00001202#endif /* which OS */
1203} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001204
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001205#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001206/* A helper function for abspath on win32 */
1207static PyObject *
1208posix__getfullpathname(PyObject *self, PyObject *args)
1209{
1210 /* assume encoded strings wont more than double no of chars */
1211 char inbuf[MAX_PATH*2];
1212 char *inbufp = inbuf;
1213 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1214 char outbuf[MAX_PATH*2];
1215 char *temp;
Tim Peters5aa91602002-01-30 05:46:57 +00001216 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1217 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001218 &insize))
1219 return NULL;
1220 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1221 outbuf, &temp))
1222 return win32_error("GetFullPathName", inbuf);
1223 return PyString_FromString(outbuf);
1224} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001225#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001226
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001227PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001228"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001229Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001230
Barry Warsaw53699e91996-12-10 23:23:01 +00001231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001232posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001233{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001234 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001235 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001236 int mode = 0777;
Tim Peters5aa91602002-01-30 05:46:57 +00001237 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001238 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001239 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001240 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001241#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001242 res = mkdir(path);
1243#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001244 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001245#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001246 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001247 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001248 return posix_error_with_allocated_filename(path);
1249 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001250 Py_INCREF(Py_None);
1251 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252}
1253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001254
Guido van Rossumb6775db1994-08-01 11:34:53 +00001255#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001256#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1257#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1258#include <sys/resource.h>
1259#endif
1260#endif
1261
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001262PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001263"nice(inc) -> new_priority\n\n\
1264Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001265
Barry Warsaw53699e91996-12-10 23:23:01 +00001266static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001267posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001268{
1269 int increment, value;
1270
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001271 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001272 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001273
1274 /* There are two flavours of 'nice': one that returns the new
1275 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001276 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1277 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001278
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001279 If we are of the nice family that returns the new priority, we
1280 need to clear errno before the call, and check if errno is filled
1281 before calling posix_error() on a returnvalue of -1, because the
1282 -1 may be the actual new priority! */
1283
1284 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001285 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001286#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001287 if (value == 0)
1288 value = getpriority(PRIO_PROCESS, 0);
1289#endif
1290 if (value == -1 && errno != 0)
1291 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001292 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001293 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001294}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001295#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001296
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001297
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001298PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001299"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001300Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001301
Barry Warsaw53699e91996-12-10 23:23:01 +00001302static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001303posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001304{
Mark Hammondef8b6542001-05-13 08:04:26 +00001305 return posix_2str(args, "etet:rename", rename);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001306}
1307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001308
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001309PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001310"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001311Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001312
Barry Warsaw53699e91996-12-10 23:23:01 +00001313static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001314posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001315{
Mark Hammondef8b6542001-05-13 08:04:26 +00001316 return posix_1str(args, "et:rmdir", rmdir);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001317}
1318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001319
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001320PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001321"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001322Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001323
Barry Warsaw53699e91996-12-10 23:23:01 +00001324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001325posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001326{
Mark Hammondef8b6542001-05-13 08:04:26 +00001327 return posix_do_stat(self, args, "et:stat", STAT);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001328}
1329
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001330
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001331#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001332PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001333"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001334Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001335
Barry Warsaw53699e91996-12-10 23:23:01 +00001336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001337posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001338{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001339 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001340 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001341 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001342 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001343 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001344 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001345 Py_END_ALLOW_THREADS
1346 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001347}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001348#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001349
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001350
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001351PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001352"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001353Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001354
Barry Warsaw53699e91996-12-10 23:23:01 +00001355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001356posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001357{
1358 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001359 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001360 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001361 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362 if (i < 0)
1363 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001364 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365}
1366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001368PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001369"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001370Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001371
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001372PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001373"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001374Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001375
Barry Warsaw53699e91996-12-10 23:23:01 +00001376static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001377posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001378{
Mark Hammondef8b6542001-05-13 08:04:26 +00001379 return posix_1str(args, "et:remove", unlink);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001380}
1381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001382
Guido van Rossumb6775db1994-08-01 11:34:53 +00001383#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001384PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001385"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001386Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001387
Barry Warsaw53699e91996-12-10 23:23:01 +00001388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001389posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001390{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001391 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001392 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001393 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001394 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001395 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001396 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001397 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001398 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001399 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001400 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001401 u.sysname,
1402 u.nodename,
1403 u.release,
1404 u.version,
1405 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001406}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001407#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001408
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001409static int
1410extract_time(PyObject *t, long* sec, long* usec)
1411{
1412 long intval;
1413 if (PyFloat_Check(t)) {
1414 double tval = PyFloat_AsDouble(t);
1415 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1416 if (!intobj)
1417 return -1;
1418 intval = PyInt_AsLong(intobj);
1419 Py_DECREF(intobj);
1420 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001421 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001422 if (*usec < 0)
1423 /* If rounding gave us a negative number,
1424 truncate. */
1425 *usec = 0;
1426 return 0;
1427 }
1428 intval = PyInt_AsLong(t);
1429 if (intval == -1 && PyErr_Occurred())
1430 return -1;
1431 *sec = intval;
1432 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001433 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001434}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001435
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001436PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001437"utime(path, (atime, utime))\n\
1438utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001439Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001440second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001441
Barry Warsaw53699e91996-12-10 23:23:01 +00001442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001443posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001444{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001445 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001446 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001447 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001448 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001449
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001450#if defined(HAVE_UTIMES)
1451 struct timeval buf[2];
1452#define ATIME buf[0].tv_sec
1453#define MTIME buf[1].tv_sec
1454#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001455/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001456 struct utimbuf buf;
1457#define ATIME buf.actime
1458#define MTIME buf.modtime
1459#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001460#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001461 time_t buf[2];
1462#define ATIME buf[0]
1463#define MTIME buf[1]
1464#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001465#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001466
Barry Warsaw3cef8562000-05-01 16:17:24 +00001467 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001468 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001469 if (arg == Py_None) {
1470 /* optional time values not given */
1471 Py_BEGIN_ALLOW_THREADS
1472 res = utime(path, NULL);
1473 Py_END_ALLOW_THREADS
1474 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001475 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001476 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001477 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001478 return NULL;
1479 }
1480 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001481 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1482 &atime, &ausec) == -1)
1483 return NULL;
1484 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1485 &mtime, &musec) == -1)
1486 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001487 ATIME = atime;
1488 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001489#ifdef HAVE_UTIMES
1490 buf[0].tv_usec = ausec;
1491 buf[1].tv_usec = musec;
1492 Py_BEGIN_ALLOW_THREADS
1493 res = utimes(path, buf);
1494 Py_END_ALLOW_THREADS
1495#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001496 Py_BEGIN_ALLOW_THREADS
1497 res = utime(path, UTIME_ARG);
1498 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001499#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00001500 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001501 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001502 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001503 Py_INCREF(Py_None);
1504 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001505#undef UTIME_ARG
1506#undef ATIME
1507#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001508}
1509
Guido van Rossum85e3b011991-06-03 12:42:10 +00001510
Guido van Rossum3b066191991-06-04 19:40:25 +00001511/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001512
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001513PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001514"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001515Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001516
Barry Warsaw53699e91996-12-10 23:23:01 +00001517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001518posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001519{
1520 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001521 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001522 return NULL;
1523 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001524 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001525}
1526
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001527
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001528#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001529PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001530"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001531Execute an executable path with arguments, replacing current process.\n\
1532\n\
1533 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001534 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001535
Barry Warsaw53699e91996-12-10 23:23:01 +00001536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001537posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001538{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001539 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001540 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001541 char **argvlist;
1542 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001543 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001544
Guido van Rossum89b33251993-10-22 14:26:06 +00001545 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001546 argv is a list or tuple of strings. */
1547
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001548 if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001549 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001550 if (PyList_Check(argv)) {
1551 argc = PyList_Size(argv);
1552 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001553 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001554 else if (PyTuple_Check(argv)) {
1555 argc = PyTuple_Size(argv);
1556 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001557 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001558 else {
Fred Drake661ea262000-10-24 19:57:45 +00001559 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Guido van Rossum50422b42000-04-26 20:34:28 +00001560 return NULL;
1561 }
1562
1563 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001564 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001565 return NULL;
1566 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001567
Barry Warsaw53699e91996-12-10 23:23:01 +00001568 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001569 if (argvlist == NULL)
1570 return NULL;
1571 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001572 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1573 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001574 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001575 "execv() arg 2 must contain only strings");
Guido van Rossum50422b42000-04-26 20:34:28 +00001576 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001577
Guido van Rossum85e3b011991-06-03 12:42:10 +00001578 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001579 }
1580 argvlist[argc] = NULL;
1581
Guido van Rossumb6775db1994-08-01 11:34:53 +00001582#ifdef BAD_EXEC_PROTOTYPES
1583 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001584#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001585 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001586#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001587
Guido van Rossum85e3b011991-06-03 12:42:10 +00001588 /* If we get here it's definitely an error */
1589
Barry Warsaw53699e91996-12-10 23:23:01 +00001590 PyMem_DEL(argvlist);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001591 return posix_error();
1592}
1593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001595PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001596"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001597Execute a path with arguments and environment, replacing current process.\n\
1598\n\
1599 path: path of executable file\n\
1600 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001601 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001602
Barry Warsaw53699e91996-12-10 23:23:01 +00001603static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001604posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001605{
1606 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001607 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001608 char **argvlist;
1609 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001610 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001611 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001612 PyObject *(*getitem)(PyObject *, int);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001613
1614 /* execve has three arguments: (path, argv, env), where
1615 argv is a list or tuple of strings and env is a dictionary
1616 like posix.environ. */
1617
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001618 if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001619 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001620 if (PyList_Check(argv)) {
1621 argc = PyList_Size(argv);
1622 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001623 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001624 else if (PyTuple_Check(argv)) {
1625 argc = PyTuple_Size(argv);
1626 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001627 }
1628 else {
Fred Drake661ea262000-10-24 19:57:45 +00001629 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001630 return NULL;
1631 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001632 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001633 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001634 return NULL;
1635 }
1636
Guido van Rossum50422b42000-04-26 20:34:28 +00001637 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00001638 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00001639 "execve() arg 2 must not be empty");
Guido van Rossum50422b42000-04-26 20:34:28 +00001640 return NULL;
1641 }
1642
Barry Warsaw53699e91996-12-10 23:23:01 +00001643 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001644 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001645 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001646 return NULL;
1647 }
1648 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001649 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001650 "s;execve() arg 2 must contain only strings",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001651 &argvlist[i]))
1652 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001653 goto fail_1;
1654 }
1655 }
1656 argvlist[argc] = NULL;
1657
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001658 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00001659 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001660 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001661 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001662 goto fail_1;
1663 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001664 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001665 keys = PyMapping_Keys(env);
1666 vals = PyMapping_Values(env);
1667 if (!keys || !vals)
1668 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001669
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001670 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001671 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001672 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001673
1674 key = PyList_GetItem(keys, pos);
1675 val = PyList_GetItem(vals, pos);
1676 if (!key || !val)
1677 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001678
Fred Drake661ea262000-10-24 19:57:45 +00001679 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
1680 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00001681 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001682 goto fail_2;
1683 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00001684
1685#if defined(PYOS_OS2)
1686 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1687 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1688#endif
Tim Petersc8996f52001-12-03 20:41:00 +00001689 len = PyString_Size(key) + PyString_Size(val) + 2;
1690 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001691 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001692 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001693 goto fail_2;
1694 }
Tim Petersc8996f52001-12-03 20:41:00 +00001695 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001696 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001697#if defined(PYOS_OS2)
1698 }
1699#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001700 }
1701 envlist[envc] = 0;
1702
Guido van Rossumb6775db1994-08-01 11:34:53 +00001703
1704#ifdef BAD_EXEC_PROTOTYPES
1705 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001706#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001707 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001708#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00001709
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001710 /* If we get here it's definitely an error */
1711
1712 (void) posix_error();
1713
1714 fail_2:
1715 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00001716 PyMem_DEL(envlist[envc]);
1717 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001718 fail_1:
Barry Warsaw53699e91996-12-10 23:23:01 +00001719 PyMem_DEL(argvlist);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00001720 Py_XDECREF(vals);
1721 Py_XDECREF(keys);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001722 return NULL;
1723}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001724#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00001725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001726
Guido van Rossuma1065681999-01-25 23:20:23 +00001727#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001728PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001729"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001730Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001731\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001732 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001733 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001734 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001735
1736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001737posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001738{
1739 char *path;
1740 PyObject *argv;
1741 char **argvlist;
1742 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00001743 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001744 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001745
1746 /* spawnv has three arguments: (mode, path, argv), where
1747 argv is a list or tuple of strings. */
1748
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001749 if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00001750 return NULL;
1751 if (PyList_Check(argv)) {
1752 argc = PyList_Size(argv);
1753 getitem = PyList_GetItem;
1754 }
1755 else if (PyTuple_Check(argv)) {
1756 argc = PyTuple_Size(argv);
1757 getitem = PyTuple_GetItem;
1758 }
1759 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00001760 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001761 return NULL;
1762 }
1763
1764 argvlist = PyMem_NEW(char *, argc+1);
1765 if (argvlist == NULL)
1766 return NULL;
1767 for (i = 0; i < argc; i++) {
1768 if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1769 PyMem_DEL(argvlist);
Tim Peters5aa91602002-01-30 05:46:57 +00001770 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001771 "spawnv() arg 2 must contain only strings");
Fred Drake137507e2000-06-01 02:02:46 +00001772 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00001773 }
1774 }
1775 argvlist[argc] = NULL;
1776
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001777#if defined(PYOS_OS2) && defined(PYCC_GCC)
1778 Py_BEGIN_ALLOW_THREADS
1779 spawnval = spawnv(mode, path, argvlist);
1780 Py_END_ALLOW_THREADS
1781#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001782 if (mode == _OLD_P_OVERLAY)
1783 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00001784
Tim Peters25059d32001-12-07 20:35:43 +00001785 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001786 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00001787 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001788#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001789
Guido van Rossuma1065681999-01-25 23:20:23 +00001790 PyMem_DEL(argvlist);
1791
Fred Drake699f3522000-06-29 21:12:41 +00001792 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001793 return posix_error();
1794 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001795#if SIZEOF_LONG == SIZEOF_VOID_P
1796 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001797#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001798 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001799#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001800}
1801
1802
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001803PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001804"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00001805Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001806\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00001807 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00001808 path: path of executable file\n\
1809 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001810 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00001811
1812static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001813posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00001814{
1815 char *path;
1816 PyObject *argv, *env;
1817 char **argvlist;
1818 char **envlist;
1819 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1820 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00001821 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001822 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00001823
1824 /* spawnve has four arguments: (mode, path, argv, env), where
1825 argv is a list or tuple of strings and env is a dictionary
1826 like posix.environ. */
1827
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001828 if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00001829 return NULL;
1830 if (PyList_Check(argv)) {
1831 argc = PyList_Size(argv);
1832 getitem = PyList_GetItem;
1833 }
1834 else if (PyTuple_Check(argv)) {
1835 argc = PyTuple_Size(argv);
1836 getitem = PyTuple_GetItem;
1837 }
1838 else {
Fred Drake661ea262000-10-24 19:57:45 +00001839 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Guido van Rossuma1065681999-01-25 23:20:23 +00001840 return NULL;
1841 }
1842 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00001843 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Guido van Rossuma1065681999-01-25 23:20:23 +00001844 return NULL;
1845 }
1846
1847 argvlist = PyMem_NEW(char *, argc+1);
1848 if (argvlist == NULL) {
1849 PyErr_NoMemory();
1850 return NULL;
1851 }
1852 for (i = 0; i < argc; i++) {
1853 if (!PyArg_Parse((*getitem)(argv, i),
Fred Drake661ea262000-10-24 19:57:45 +00001854 "s;spawnve() arg 2 must contain only strings",
Guido van Rossuma1065681999-01-25 23:20:23 +00001855 &argvlist[i]))
1856 {
1857 goto fail_1;
1858 }
1859 }
1860 argvlist[argc] = NULL;
1861
Jeremy Hylton03657cf2000-07-12 13:05:33 +00001862 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00001863 envlist = PyMem_NEW(char *, i + 1);
1864 if (envlist == NULL) {
1865 PyErr_NoMemory();
1866 goto fail_1;
1867 }
1868 envc = 0;
1869 keys = PyMapping_Keys(env);
1870 vals = PyMapping_Values(env);
1871 if (!keys || !vals)
1872 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001873
Guido van Rossuma1065681999-01-25 23:20:23 +00001874 for (pos = 0; pos < i; pos++) {
1875 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00001876 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00001877
1878 key = PyList_GetItem(keys, pos);
1879 val = PyList_GetItem(vals, pos);
1880 if (!key || !val)
1881 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00001882
Fred Drake661ea262000-10-24 19:57:45 +00001883 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
1884 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00001885 {
1886 goto fail_2;
1887 }
Tim Petersc8996f52001-12-03 20:41:00 +00001888 len = PyString_Size(key) + PyString_Size(val) + 2;
1889 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00001890 if (p == NULL) {
1891 PyErr_NoMemory();
1892 goto fail_2;
1893 }
Tim Petersc8996f52001-12-03 20:41:00 +00001894 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00001895 envlist[envc++] = p;
1896 }
1897 envlist[envc] = 0;
1898
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001899#if defined(PYOS_OS2) && defined(PYCC_GCC)
1900 Py_BEGIN_ALLOW_THREADS
1901 spawnval = spawnve(mode, path, argvlist, envlist);
1902 Py_END_ALLOW_THREADS
1903#else
Guido van Rossum246bc171999-02-01 23:54:31 +00001904 if (mode == _OLD_P_OVERLAY)
1905 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00001906
1907 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00001908 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00001909 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001910#endif
Tim Peters25059d32001-12-07 20:35:43 +00001911
Fred Drake699f3522000-06-29 21:12:41 +00001912 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00001913 (void) posix_error();
1914 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001915#if SIZEOF_LONG == SIZEOF_VOID_P
1916 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001917#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00001918 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00001919#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00001920
1921 fail_2:
1922 while (--envc >= 0)
1923 PyMem_DEL(envlist[envc]);
1924 PyMem_DEL(envlist);
1925 fail_1:
1926 PyMem_DEL(argvlist);
1927 Py_XDECREF(vals);
1928 Py_XDECREF(keys);
1929 return res;
1930}
1931#endif /* HAVE_SPAWNV */
1932
1933
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001934#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001935PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001936"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001937Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1938\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001939Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00001940
1941static PyObject *
1942posix_fork1(self, args)
1943 PyObject *self;
1944 PyObject *args;
1945{
1946 int pid;
1947 if (!PyArg_ParseTuple(args, ":fork1"))
1948 return NULL;
1949 pid = fork1();
1950 if (pid == -1)
1951 return posix_error();
1952 PyOS_AfterFork();
1953 return PyInt_FromLong((long)pid);
1954}
1955#endif
1956
1957
Guido van Rossumad0ee831995-03-01 10:34:45 +00001958#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001959PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001960"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001961Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001962Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001963
Barry Warsaw53699e91996-12-10 23:23:01 +00001964static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001965posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001966{
1967 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001968 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001969 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001970 pid = fork();
1971 if (pid == -1)
1972 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00001973 if (pid == 0)
1974 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00001975 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001976}
Guido van Rossumad0ee831995-03-01 10:34:45 +00001977#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00001978
Fred Drake8cef4cf2000-06-28 16:40:38 +00001979#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1980#ifdef HAVE_PTY_H
1981#include <pty.h>
1982#else
1983#ifdef HAVE_LIBUTIL_H
1984#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00001985#endif /* HAVE_LIBUTIL_H */
1986#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00001987#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00001988
Thomas Wouters70c21a12000-07-14 14:28:33 +00001989#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001990PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001991"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001992Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00001993
1994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001995posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00001996{
1997 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00001998#ifndef HAVE_OPENPTY
1999 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002000#endif
2001
Fred Drake8cef4cf2000-06-28 16:40:38 +00002002 if (!PyArg_ParseTuple(args, ":openpty"))
2003 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002004
2005#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002006 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2007 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00002008#else
2009 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2010 if (slave_name == NULL)
2011 return posix_error();
2012
2013 slave_fd = open(slave_name, O_RDWR);
2014 if (slave_fd < 0)
2015 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002016#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002017
Fred Drake8cef4cf2000-06-28 16:40:38 +00002018 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002019
Fred Drake8cef4cf2000-06-28 16:40:38 +00002020}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002021#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002022
2023#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002024PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002025"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002026Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2027Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002028To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002029
2030static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002031posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002032{
2033 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002034
Fred Drake8cef4cf2000-06-28 16:40:38 +00002035 if (!PyArg_ParseTuple(args, ":forkpty"))
2036 return NULL;
2037 pid = forkpty(&master_fd, NULL, NULL, NULL);
2038 if (pid == -1)
2039 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002040 if (pid == 0)
2041 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002042 return Py_BuildValue("(ii)", pid, master_fd);
2043}
2044#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002045
Guido van Rossumad0ee831995-03-01 10:34:45 +00002046#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002048"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002049Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002050
Barry Warsaw53699e91996-12-10 23:23:01 +00002051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002052posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002053{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002054 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002055 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002056 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002057}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002058#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002060
Guido van Rossumad0ee831995-03-01 10:34:45 +00002061#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002062PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002063"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002064Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002065
Barry Warsaw53699e91996-12-10 23:23:01 +00002066static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002067posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002068{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002069 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002070 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002071 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002072}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002073#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
Guido van Rossumad0ee831995-03-01 10:34:45 +00002076#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002078"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002079Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002080
Barry Warsaw53699e91996-12-10 23:23:01 +00002081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002082posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002083{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002084 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002085 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002087}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002088#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002089
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002090
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002091PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002092"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002093Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002094
Barry Warsaw53699e91996-12-10 23:23:01 +00002095static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002096posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002097{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002098 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002099 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002100 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002101}
2102
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002103
Fred Drakec9680921999-12-13 16:37:25 +00002104#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002105PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002106"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002107Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002108
2109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002110posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002111{
2112 PyObject *result = NULL;
2113
2114 if (PyArg_ParseTuple(args, ":getgroups")) {
2115#ifdef NGROUPS_MAX
2116#define MAX_GROUPS NGROUPS_MAX
2117#else
2118 /* defined to be 16 on Solaris7, so this should be a small number */
2119#define MAX_GROUPS 64
2120#endif
2121 gid_t grouplist[MAX_GROUPS];
2122 int n;
2123
2124 n = getgroups(MAX_GROUPS, grouplist);
2125 if (n < 0)
2126 posix_error();
2127 else {
2128 result = PyList_New(n);
2129 if (result != NULL) {
2130 PyObject *o;
2131 int i;
2132 for (i = 0; i < n; ++i) {
2133 o = PyInt_FromLong((long)grouplist[i]);
2134 if (o == NULL) {
2135 Py_DECREF(result);
2136 result = NULL;
2137 break;
2138 }
2139 PyList_SET_ITEM(result, i, o);
2140 }
2141 }
2142 }
2143 }
2144 return result;
2145}
2146#endif
2147
Martin v. Löwis606edc12002-06-13 21:09:11 +00002148#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002149PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002150"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002151Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002152
2153static PyObject *
2154posix_getpgid(PyObject *self, PyObject *args)
2155{
2156 int pid, pgid;
2157 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2158 return NULL;
2159 pgid = getpgid(pid);
2160 if (pgid < 0)
2161 return posix_error();
2162 return PyInt_FromLong((long)pgid);
2163}
2164#endif /* HAVE_GETPGID */
2165
2166
Guido van Rossumb6775db1994-08-01 11:34:53 +00002167#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002168PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002169"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002170Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002171
Barry Warsaw53699e91996-12-10 23:23:01 +00002172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002173posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002174{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002175 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002176 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002177#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002178 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002179#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002180 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002181#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002182}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002183#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002184
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002185
Guido van Rossumb6775db1994-08-01 11:34:53 +00002186#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002187PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002188"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002189Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002190
Barry Warsaw53699e91996-12-10 23:23:01 +00002191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002192posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002193{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002194 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002195 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002196#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002197 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002198#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002199 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002200#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002201 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002202 Py_INCREF(Py_None);
2203 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002204}
2205
Guido van Rossumb6775db1994-08-01 11:34:53 +00002206#endif /* HAVE_SETPGRP */
2207
Guido van Rossumad0ee831995-03-01 10:34:45 +00002208#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002209PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002210"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002211Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002212
Barry Warsaw53699e91996-12-10 23:23:01 +00002213static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002214posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002215{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002216 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002217 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002218 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002219}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002220#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002222
Fred Drake12c6e2d1999-12-14 21:25:03 +00002223#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002224PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002225"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002226Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002227
2228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002229posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002230{
2231 PyObject *result = NULL;
2232
2233 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002234 char *name;
2235 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002236
Fred Drakea30680b2000-12-06 21:24:28 +00002237 errno = 0;
2238 name = getlogin();
2239 if (name == NULL) {
2240 if (errno)
2241 posix_error();
2242 else
2243 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002244 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002245 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002246 else
2247 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002248 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002249 }
2250 return result;
2251}
2252#endif
2253
Guido van Rossumad0ee831995-03-01 10:34:45 +00002254#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002255PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002256"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002257Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002258
Barry Warsaw53699e91996-12-10 23:23:01 +00002259static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002260posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002261{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002262 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002263 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002264 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002265}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002266#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002268
Guido van Rossumad0ee831995-03-01 10:34:45 +00002269#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002270PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002271"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002272Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002273
Barry Warsaw53699e91996-12-10 23:23:01 +00002274static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002275posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002276{
2277 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002278 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002279 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002280#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002281 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2282 APIRET rc;
2283 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002284 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002285
2286 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2287 APIRET rc;
2288 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002289 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002290
2291 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002292 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002293#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002294 if (kill(pid, sig) == -1)
2295 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002296#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002297 Py_INCREF(Py_None);
2298 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002299}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002300#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002301
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002302#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002303PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002304"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002305Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002306
2307static PyObject *
2308posix_killpg(PyObject *self, PyObject *args)
2309{
2310 int pgid, sig;
2311 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2312 return NULL;
2313 if (killpg(pgid, sig) == -1)
2314 return posix_error();
2315 Py_INCREF(Py_None);
2316 return Py_None;
2317}
2318#endif
2319
Guido van Rossumc0125471996-06-28 18:55:32 +00002320#ifdef HAVE_PLOCK
2321
2322#ifdef HAVE_SYS_LOCK_H
2323#include <sys/lock.h>
2324#endif
2325
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002326PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002327"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002328Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002329
Barry Warsaw53699e91996-12-10 23:23:01 +00002330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002331posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002332{
2333 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002334 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002335 return NULL;
2336 if (plock(op) == -1)
2337 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002338 Py_INCREF(Py_None);
2339 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002340}
2341#endif
2342
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002343
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002344#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002345PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002346"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002347Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002348
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002349#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002350#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002351static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002352async_system(const char *command)
2353{
2354 char *p, errormsg[256], args[1024];
2355 RESULTCODES rcodes;
2356 APIRET rc;
2357 char *shell = getenv("COMSPEC");
2358 if (!shell)
2359 shell = "cmd";
2360
2361 strcpy(args, shell);
2362 p = &args[ strlen(args)+1 ];
2363 strcpy(p, "/c ");
2364 strcat(p, command);
2365 p += strlen(p) + 1;
2366 *p = '\0';
2367
2368 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002369 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002370 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002371 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002372 &rcodes, shell);
2373 return rc;
2374}
2375
Guido van Rossumd48f2521997-12-05 22:19:34 +00002376static FILE *
2377popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002378{
2379 HFILE rhan, whan;
2380 FILE *retfd = NULL;
2381 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2382
Guido van Rossumd48f2521997-12-05 22:19:34 +00002383 if (rc != NO_ERROR) {
2384 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002385 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002386 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002387
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002388 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2389 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002390
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002391 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2392 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002393
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002394 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2395 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002396
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002397 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002398 }
2399
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002400 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2401 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002402
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002403 if (rc == NO_ERROR)
2404 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2405
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002406 close(oldfd); /* And Close Saved STDOUT Handle */
2407 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002408
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002409 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2410 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002411
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002412 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2413 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002414
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002415 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2416 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002417
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002418 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002419 }
2420
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002421 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2422 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002423
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002424 if (rc == NO_ERROR)
2425 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2426
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002427 close(oldfd); /* And Close Saved STDIN Handle */
2428 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002429
Guido van Rossumd48f2521997-12-05 22:19:34 +00002430 } else {
2431 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002432 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002433 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002434}
2435
2436static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002437posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002438{
2439 char *name;
2440 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002441 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002442 FILE *fp;
2443 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002444 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002445 return NULL;
2446 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002447 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002448 Py_END_ALLOW_THREADS
2449 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002450 return os2_error(err);
2451
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002452 f = PyFile_FromFile(fp, name, mode, fclose);
2453 if (f != NULL)
2454 PyFile_SetBufSize(f, bufsize);
2455 return f;
2456}
2457
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002458#elif defined(PYCC_GCC)
2459
2460/* standard posix version of popen() support */
2461static PyObject *
2462posix_popen(PyObject *self, PyObject *args)
2463{
2464 char *name;
2465 char *mode = "r";
2466 int bufsize = -1;
2467 FILE *fp;
2468 PyObject *f;
2469 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2470 return NULL;
2471 Py_BEGIN_ALLOW_THREADS
2472 fp = popen(name, mode);
2473 Py_END_ALLOW_THREADS
2474 if (fp == NULL)
2475 return posix_error();
2476 f = PyFile_FromFile(fp, name, mode, pclose);
2477 if (f != NULL)
2478 PyFile_SetBufSize(f, bufsize);
2479 return f;
2480}
2481
2482/* fork() under OS/2 has lots'o'warts
2483 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2484 * most of this code is a ripoff of the win32 code, but using the
2485 * capabilities of EMX's C library routines
2486 */
2487
2488/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2489#define POPEN_1 1
2490#define POPEN_2 2
2491#define POPEN_3 3
2492#define POPEN_4 4
2493
2494static PyObject *_PyPopen(char *, int, int, int);
2495static int _PyPclose(FILE *file);
2496
2497/*
2498 * Internal dictionary mapping popen* file pointers to process handles,
2499 * for use when retrieving the process exit code. See _PyPclose() below
2500 * for more information on this dictionary's use.
2501 */
2502static PyObject *_PyPopenProcs = NULL;
2503
2504/* os2emx version of popen2()
2505 *
2506 * The result of this function is a pipe (file) connected to the
2507 * process's stdin, and a pipe connected to the process's stdout.
2508 */
2509
2510static PyObject *
2511os2emx_popen2(PyObject *self, PyObject *args)
2512{
2513 PyObject *f;
2514 int tm=0;
2515
2516 char *cmdstring;
2517 char *mode = "t";
2518 int bufsize = -1;
2519 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2520 return NULL;
2521
2522 if (*mode == 't')
2523 tm = O_TEXT;
2524 else if (*mode != 'b') {
2525 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2526 return NULL;
2527 } else
2528 tm = O_BINARY;
2529
2530 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2531
2532 return f;
2533}
2534
2535/*
2536 * Variation on os2emx.popen2
2537 *
2538 * The result of this function is 3 pipes - the process's stdin,
2539 * stdout and stderr
2540 */
2541
2542static PyObject *
2543os2emx_popen3(PyObject *self, PyObject *args)
2544{
2545 PyObject *f;
2546 int tm = 0;
2547
2548 char *cmdstring;
2549 char *mode = "t";
2550 int bufsize = -1;
2551 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2552 return NULL;
2553
2554 if (*mode == 't')
2555 tm = O_TEXT;
2556 else if (*mode != 'b') {
2557 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2558 return NULL;
2559 } else
2560 tm = O_BINARY;
2561
2562 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
2563
2564 return f;
2565}
2566
2567/*
2568 * Variation on os2emx.popen2
2569 *
2570 * The result of this function is 2 pipes - the processes stdin,
2571 * and stdout+stderr combined as a single pipe.
2572 */
2573
2574static PyObject *
2575os2emx_popen4(PyObject *self, PyObject *args)
2576{
2577 PyObject *f;
2578 int tm = 0;
2579
2580 char *cmdstring;
2581 char *mode = "t";
2582 int bufsize = -1;
2583 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2584 return NULL;
2585
2586 if (*mode == 't')
2587 tm = O_TEXT;
2588 else if (*mode != 'b') {
2589 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2590 return NULL;
2591 } else
2592 tm = O_BINARY;
2593
2594 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
2595
2596 return f;
2597}
2598
2599/* a couple of structures for convenient handling of multiple
2600 * file handles and pipes
2601 */
2602struct file_ref
2603{
2604 int handle;
2605 int flags;
2606};
2607
2608struct pipe_ref
2609{
2610 int rd;
2611 int wr;
2612};
2613
2614/* The following code is derived from the win32 code */
2615
2616static PyObject *
2617_PyPopen(char *cmdstring, int mode, int n, int bufsize)
2618{
2619 struct file_ref stdio[3];
2620 struct pipe_ref p_fd[3];
2621 FILE *p_s[3];
2622 int file_count, i, pipe_err, pipe_pid;
2623 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
2624 PyObject *f, *p_f[3];
2625
2626 /* file modes for subsequent fdopen's on pipe handles */
2627 if (mode == O_TEXT)
2628 {
2629 rd_mode = "rt";
2630 wr_mode = "wt";
2631 }
2632 else
2633 {
2634 rd_mode = "rb";
2635 wr_mode = "wb";
2636 }
2637
2638 /* prepare shell references */
2639 if ((shell = getenv("EMXSHELL")) == NULL)
2640 if ((shell = getenv("COMSPEC")) == NULL)
2641 {
2642 errno = ENOENT;
2643 return posix_error();
2644 }
2645
2646 sh_name = _getname(shell);
2647 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
2648 opt = "/c";
2649 else
2650 opt = "-c";
2651
2652 /* save current stdio fds + their flags, and set not inheritable */
2653 i = pipe_err = 0;
2654 while (pipe_err >= 0 && i < 3)
2655 {
2656 pipe_err = stdio[i].handle = dup(i);
2657 stdio[i].flags = fcntl(i, F_GETFD, 0);
2658 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
2659 i++;
2660 }
2661 if (pipe_err < 0)
2662 {
2663 /* didn't get them all saved - clean up and bail out */
2664 int saved_err = errno;
2665 while (i-- > 0)
2666 {
2667 close(stdio[i].handle);
2668 }
2669 errno = saved_err;
2670 return posix_error();
2671 }
2672
2673 /* create pipe ends */
2674 file_count = 2;
2675 if (n == POPEN_3)
2676 file_count = 3;
2677 i = pipe_err = 0;
2678 while ((pipe_err == 0) && (i < file_count))
2679 pipe_err = pipe((int *)&p_fd[i++]);
2680 if (pipe_err < 0)
2681 {
2682 /* didn't get them all made - clean up and bail out */
2683 while (i-- > 0)
2684 {
2685 close(p_fd[i].wr);
2686 close(p_fd[i].rd);
2687 }
2688 errno = EPIPE;
2689 return posix_error();
2690 }
2691
2692 /* change the actual standard IO streams over temporarily,
2693 * making the retained pipe ends non-inheritable
2694 */
2695 pipe_err = 0;
2696
2697 /* - stdin */
2698 if (dup2(p_fd[0].rd, 0) == 0)
2699 {
2700 close(p_fd[0].rd);
2701 i = fcntl(p_fd[0].wr, F_GETFD, 0);
2702 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
2703 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
2704 {
2705 close(p_fd[0].wr);
2706 pipe_err = -1;
2707 }
2708 }
2709 else
2710 {
2711 pipe_err = -1;
2712 }
2713
2714 /* - stdout */
2715 if (pipe_err == 0)
2716 {
2717 if (dup2(p_fd[1].wr, 1) == 1)
2718 {
2719 close(p_fd[1].wr);
2720 i = fcntl(p_fd[1].rd, F_GETFD, 0);
2721 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
2722 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
2723 {
2724 close(p_fd[1].rd);
2725 pipe_err = -1;
2726 }
2727 }
2728 else
2729 {
2730 pipe_err = -1;
2731 }
2732 }
2733
2734 /* - stderr, as required */
2735 if (pipe_err == 0)
2736 switch (n)
2737 {
2738 case POPEN_3:
2739 {
2740 if (dup2(p_fd[2].wr, 2) == 2)
2741 {
2742 close(p_fd[2].wr);
2743 i = fcntl(p_fd[2].rd, F_GETFD, 0);
2744 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
2745 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
2746 {
2747 close(p_fd[2].rd);
2748 pipe_err = -1;
2749 }
2750 }
2751 else
2752 {
2753 pipe_err = -1;
2754 }
2755 break;
2756 }
2757
2758 case POPEN_4:
2759 {
2760 if (dup2(1, 2) != 2)
2761 {
2762 pipe_err = -1;
2763 }
2764 break;
2765 }
2766 }
2767
2768 /* spawn the child process */
2769 if (pipe_err == 0)
2770 {
2771 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
2772 if (pipe_pid == -1)
2773 {
2774 pipe_err = -1;
2775 }
2776 else
2777 {
2778 /* save the PID into the FILE structure
2779 * NOTE: this implementation doesn't actually
2780 * take advantage of this, but do it for
2781 * completeness - AIM Apr01
2782 */
2783 for (i = 0; i < file_count; i++)
2784 p_s[i]->_pid = pipe_pid;
2785 }
2786 }
2787
2788 /* reset standard IO to normal */
2789 for (i = 0; i < 3; i++)
2790 {
2791 dup2(stdio[i].handle, i);
2792 fcntl(i, F_SETFD, stdio[i].flags);
2793 close(stdio[i].handle);
2794 }
2795
2796 /* if any remnant problems, clean up and bail out */
2797 if (pipe_err < 0)
2798 {
2799 for (i = 0; i < 3; i++)
2800 {
2801 close(p_fd[i].rd);
2802 close(p_fd[i].wr);
2803 }
2804 errno = EPIPE;
2805 return posix_error_with_filename(cmdstring);
2806 }
2807
2808 /* build tuple of file objects to return */
2809 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
2810 PyFile_SetBufSize(p_f[0], bufsize);
2811 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
2812 PyFile_SetBufSize(p_f[1], bufsize);
2813 if (n == POPEN_3)
2814 {
2815 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
2816 PyFile_SetBufSize(p_f[0], bufsize);
2817 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
2818 }
2819 else
2820 f = Py_BuildValue("OO", p_f[0], p_f[1]);
2821
2822 /*
2823 * Insert the files we've created into the process dictionary
2824 * all referencing the list with the process handle and the
2825 * initial number of files (see description below in _PyPclose).
2826 * Since if _PyPclose later tried to wait on a process when all
2827 * handles weren't closed, it could create a deadlock with the
2828 * child, we spend some energy here to try to ensure that we
2829 * either insert all file handles into the dictionary or none
2830 * at all. It's a little clumsy with the various popen modes
2831 * and variable number of files involved.
2832 */
2833 if (!_PyPopenProcs)
2834 {
2835 _PyPopenProcs = PyDict_New();
2836 }
2837
2838 if (_PyPopenProcs)
2839 {
2840 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
2841 int ins_rc[3];
2842
2843 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
2844 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
2845
2846 procObj = PyList_New(2);
2847 pidObj = PyInt_FromLong((long) pipe_pid);
2848 intObj = PyInt_FromLong((long) file_count);
2849
2850 if (procObj && pidObj && intObj)
2851 {
2852 PyList_SetItem(procObj, 0, pidObj);
2853 PyList_SetItem(procObj, 1, intObj);
2854
2855 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
2856 if (fileObj[0])
2857 {
2858 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
2859 fileObj[0],
2860 procObj);
2861 }
2862 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
2863 if (fileObj[1])
2864 {
2865 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
2866 fileObj[1],
2867 procObj);
2868 }
2869 if (file_count >= 3)
2870 {
2871 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
2872 if (fileObj[2])
2873 {
2874 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
2875 fileObj[2],
2876 procObj);
2877 }
2878 }
2879
2880 if (ins_rc[0] < 0 || !fileObj[0] ||
2881 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
2882 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
2883 {
2884 /* Something failed - remove any dictionary
2885 * entries that did make it.
2886 */
2887 if (!ins_rc[0] && fileObj[0])
2888 {
2889 PyDict_DelItem(_PyPopenProcs,
2890 fileObj[0]);
2891 }
2892 if (!ins_rc[1] && fileObj[1])
2893 {
2894 PyDict_DelItem(_PyPopenProcs,
2895 fileObj[1]);
2896 }
2897 if (!ins_rc[2] && fileObj[2])
2898 {
2899 PyDict_DelItem(_PyPopenProcs,
2900 fileObj[2]);
2901 }
2902 }
2903 }
2904
2905 /*
2906 * Clean up our localized references for the dictionary keys
2907 * and value since PyDict_SetItem will Py_INCREF any copies
2908 * that got placed in the dictionary.
2909 */
2910 Py_XDECREF(procObj);
2911 Py_XDECREF(fileObj[0]);
2912 Py_XDECREF(fileObj[1]);
2913 Py_XDECREF(fileObj[2]);
2914 }
2915
2916 /* Child is launched. */
2917 return f;
2918}
2919
2920/*
2921 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2922 * exit code for the child process and return as a result of the close.
2923 *
2924 * This function uses the _PyPopenProcs dictionary in order to map the
2925 * input file pointer to information about the process that was
2926 * originally created by the popen* call that created the file pointer.
2927 * The dictionary uses the file pointer as a key (with one entry
2928 * inserted for each file returned by the original popen* call) and a
2929 * single list object as the value for all files from a single call.
2930 * The list object contains the Win32 process handle at [0], and a file
2931 * count at [1], which is initialized to the total number of file
2932 * handles using that list.
2933 *
2934 * This function closes whichever handle it is passed, and decrements
2935 * the file count in the dictionary for the process handle pointed to
2936 * by this file. On the last close (when the file count reaches zero),
2937 * this function will wait for the child process and then return its
2938 * exit code as the result of the close() operation. This permits the
2939 * files to be closed in any order - it is always the close() of the
2940 * final handle that will return the exit code.
2941 */
2942
2943 /* RED_FLAG 31-Aug-2000 Tim
2944 * This is always called (today!) between a pair of
2945 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2946 * macros. So the thread running this has no valid thread state, as
2947 * far as Python is concerned. However, this calls some Python API
2948 * functions that cannot be called safely without a valid thread
2949 * state, in particular PyDict_GetItem.
2950 * As a temporary hack (although it may last for years ...), we
2951 * *rely* on not having a valid thread state in this function, in
2952 * order to create our own "from scratch".
2953 * This will deadlock if _PyPclose is ever called by a thread
2954 * holding the global lock.
2955 * (The OS/2 EMX thread support appears to cover the case where the
2956 * lock is already held - AIM Apr01)
2957 */
2958
2959static int _PyPclose(FILE *file)
2960{
2961 int result;
2962 int exit_code;
2963 int pipe_pid;
2964 PyObject *procObj, *pidObj, *intObj, *fileObj;
2965 int file_count;
2966#ifdef WITH_THREAD
2967 PyInterpreterState* pInterpreterState;
2968 PyThreadState* pThreadState;
2969#endif
2970
2971 /* Close the file handle first, to ensure it can't block the
2972 * child from exiting if it's the last handle.
2973 */
2974 result = fclose(file);
2975
2976#ifdef WITH_THREAD
2977 /* Bootstrap a valid thread state into existence. */
2978 pInterpreterState = PyInterpreterState_New();
2979 if (!pInterpreterState) {
2980 /* Well, we're hosed now! We don't have a thread
2981 * state, so can't call a nice error routine, or raise
2982 * an exception. Just die.
2983 */
2984 Py_FatalError("unable to allocate interpreter state "
2985 "when closing popen object.");
2986 return -1; /* unreachable */
2987 }
2988 pThreadState = PyThreadState_New(pInterpreterState);
2989 if (!pThreadState) {
2990 Py_FatalError("unable to allocate thread state "
2991 "when closing popen object.");
2992 return -1; /* unreachable */
2993 }
2994 /* Grab the global lock. Note that this will deadlock if the
2995 * current thread already has the lock! (see RED_FLAG comments
2996 * before this function)
2997 */
2998 PyEval_RestoreThread(pThreadState);
2999#endif
3000
3001 if (_PyPopenProcs)
3002 {
3003 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3004 (procObj = PyDict_GetItem(_PyPopenProcs,
3005 fileObj)) != NULL &&
3006 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3007 (intObj = PyList_GetItem(procObj,1)) != NULL)
3008 {
3009 pipe_pid = (int) PyInt_AsLong(pidObj);
3010 file_count = (int) PyInt_AsLong(intObj);
3011
3012 if (file_count > 1)
3013 {
3014 /* Still other files referencing process */
3015 file_count--;
3016 PyList_SetItem(procObj,1,
3017 PyInt_FromLong((long) file_count));
3018 }
3019 else
3020 {
3021 /* Last file for this process */
3022 if (result != EOF &&
3023 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3024 {
3025 /* extract exit status */
3026 if (WIFEXITED(exit_code))
3027 {
3028 result = WEXITSTATUS(exit_code);
3029 }
3030 else
3031 {
3032 errno = EPIPE;
3033 result = -1;
3034 }
3035 }
3036 else
3037 {
3038 /* Indicate failure - this will cause the file object
3039 * to raise an I/O error and translate the last
3040 * error code from errno. We do have a problem with
3041 * last errors that overlap the normal errno table,
3042 * but that's a consistent problem with the file object.
3043 */
3044 result = -1;
3045 }
3046 }
3047
3048 /* Remove this file pointer from dictionary */
3049 PyDict_DelItem(_PyPopenProcs, fileObj);
3050
3051 if (PyDict_Size(_PyPopenProcs) == 0)
3052 {
3053 Py_DECREF(_PyPopenProcs);
3054 _PyPopenProcs = NULL;
3055 }
3056
3057 } /* if object retrieval ok */
3058
3059 Py_XDECREF(fileObj);
3060 } /* if _PyPopenProcs */
3061
3062#ifdef WITH_THREAD
3063 /* Tear down the thread & interpreter states.
3064 * Note that interpreter state clear & delete functions automatically
3065 * call the thread clear & delete functions, and indeed insist on
3066 * doing that themselves. The lock must be held during the clear, but
3067 * need not be held during the delete.
3068 */
3069 PyInterpreterState_Clear(pInterpreterState);
3070 PyEval_ReleaseThread(pThreadState);
3071 PyInterpreterState_Delete(pInterpreterState);
3072#endif
3073
3074 return result;
3075}
3076
3077#endif /* PYCC_??? */
3078
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003079#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003080
3081/*
3082 * Portable 'popen' replacement for Win32.
3083 *
3084 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3085 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003086 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003087 */
3088
3089#include <malloc.h>
3090#include <io.h>
3091#include <fcntl.h>
3092
3093/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3094#define POPEN_1 1
3095#define POPEN_2 2
3096#define POPEN_3 3
3097#define POPEN_4 4
3098
3099static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003100static int _PyPclose(FILE *file);
3101
3102/*
3103 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003104 * for use when retrieving the process exit code. See _PyPclose() below
3105 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003106 */
3107static PyObject *_PyPopenProcs = NULL;
3108
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003109
3110/* popen that works from a GUI.
3111 *
3112 * The result of this function is a pipe (file) connected to the
3113 * processes stdin or stdout, depending on the requested mode.
3114 */
3115
3116static PyObject *
3117posix_popen(PyObject *self, PyObject *args)
3118{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003119 PyObject *f, *s;
3120 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003121
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003122 char *cmdstring;
3123 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003124 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003125 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003126 return NULL;
3127
3128 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003129
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003130 if (*mode == 'r')
3131 tm = _O_RDONLY;
3132 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003133 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003134 return NULL;
3135 } else
3136 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003137
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003138 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003139 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003140 return NULL;
3141 }
3142
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003143 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003144 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003145 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003146 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003147 else
3148 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3149
3150 return f;
3151}
3152
3153/* Variation on win32pipe.popen
3154 *
3155 * The result of this function is a pipe (file) connected to the
3156 * process's stdin, and a pipe connected to the process's stdout.
3157 */
3158
3159static PyObject *
3160win32_popen2(PyObject *self, PyObject *args)
3161{
3162 PyObject *f;
3163 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003164
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003165 char *cmdstring;
3166 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003167 int bufsize = -1;
3168 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003169 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003170
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003171 if (*mode == 't')
3172 tm = _O_TEXT;
3173 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003174 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003175 return NULL;
3176 } else
3177 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003178
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003179 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003180 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003181 return NULL;
3182 }
3183
3184 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003185
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003186 return f;
3187}
3188
3189/*
3190 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003191 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003192 * The result of this function is 3 pipes - the process's stdin,
3193 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003194 */
3195
3196static PyObject *
3197win32_popen3(PyObject *self, PyObject *args)
3198{
3199 PyObject *f;
3200 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003201
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003202 char *cmdstring;
3203 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003204 int bufsize = -1;
3205 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003206 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003207
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003208 if (*mode == 't')
3209 tm = _O_TEXT;
3210 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003211 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003212 return NULL;
3213 } else
3214 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003215
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003216 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003217 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003218 return NULL;
3219 }
3220
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003221 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003222
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003223 return f;
3224}
3225
3226/*
3227 * Variation on win32pipe.popen
3228 *
Tim Peters5aa91602002-01-30 05:46:57 +00003229 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003230 * and stdout+stderr combined as a single pipe.
3231 */
3232
3233static PyObject *
3234win32_popen4(PyObject *self, PyObject *args)
3235{
3236 PyObject *f;
3237 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003238
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003239 char *cmdstring;
3240 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003241 int bufsize = -1;
3242 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003243 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003244
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003245 if (*mode == 't')
3246 tm = _O_TEXT;
3247 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003248 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003249 return NULL;
3250 } else
3251 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003252
3253 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003254 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003255 return NULL;
3256 }
3257
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003258 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003259
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003260 return f;
3261}
3262
Mark Hammond08501372001-01-31 07:30:29 +00003263static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003264_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003265 HANDLE hStdin,
3266 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003267 HANDLE hStderr,
3268 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003269{
3270 PROCESS_INFORMATION piProcInfo;
3271 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003272 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003273 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003274 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003275 int i;
3276 int x;
3277
3278 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003279 char *comshell;
3280
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003281 s1 = (char *)_alloca(i);
3282 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3283 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003284
3285 /* Explicitly check if we are using COMMAND.COM. If we are
3286 * then use the w9xpopen hack.
3287 */
3288 comshell = s1 + x;
3289 while (comshell >= s1 && *comshell != '\\')
3290 --comshell;
3291 ++comshell;
3292
3293 if (GetVersion() < 0x80000000 &&
3294 _stricmp(comshell, "command.com") != 0) {
3295 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003296 x = i + strlen(s3) + strlen(cmdstring) + 1;
3297 s2 = (char *)_alloca(x);
3298 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003299 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003300 }
3301 else {
3302 /*
Tim Peters402d5982001-08-27 06:37:48 +00003303 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3304 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003305 */
Mark Hammond08501372001-01-31 07:30:29 +00003306 char modulepath[_MAX_PATH];
3307 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003308 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3309 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003310 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003311 x = i+1;
3312 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003313 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003314 strncat(modulepath,
3315 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003316 (sizeof(modulepath)/sizeof(modulepath[0]))
3317 -strlen(modulepath));
3318 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003319 /* Eeek - file-not-found - possibly an embedding
3320 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003321 */
Tim Peters5aa91602002-01-30 05:46:57 +00003322 strncpy(modulepath,
3323 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003324 sizeof(modulepath)/sizeof(modulepath[0]));
3325 if (modulepath[strlen(modulepath)-1] != '\\')
3326 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003327 strncat(modulepath,
3328 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003329 (sizeof(modulepath)/sizeof(modulepath[0]))
3330 -strlen(modulepath));
3331 /* No where else to look - raise an easily identifiable
3332 error, rather than leaving Windows to report
3333 "file not found" - as the user is probably blissfully
3334 unaware this shim EXE is used, and it will confuse them.
3335 (well, it confused me for a while ;-)
3336 */
3337 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003338 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003339 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003340 "for popen to work with your shell "
3341 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003342 szConsoleSpawn);
3343 return FALSE;
3344 }
3345 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003346 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003347 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003348 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003349
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003350 s2 = (char *)_alloca(x);
3351 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003352 /* To maintain correct argument passing semantics,
3353 we pass the command-line as it stands, and allow
3354 quoting to be applied. w9xpopen.exe will then
3355 use its argv vector, and re-quote the necessary
3356 args for the ultimate child process.
3357 */
Tim Peters75cdad52001-11-28 22:07:30 +00003358 PyOS_snprintf(
3359 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003360 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003361 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003362 s1,
3363 s3,
3364 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003365 /* Not passing CREATE_NEW_CONSOLE has been known to
3366 cause random failures on win9x. Specifically a
3367 dialog:
3368 "Your program accessed mem currently in use at xxx"
3369 and a hopeful warning about the stability of your
3370 system.
3371 Cost is Ctrl+C wont kill children, but anyone
3372 who cares can have a go!
3373 */
3374 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003375 }
3376 }
3377
3378 /* Could be an else here to try cmd.exe / command.com in the path
3379 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003380 else {
Tim Peters402d5982001-08-27 06:37:48 +00003381 PyErr_SetString(PyExc_RuntimeError,
3382 "Cannot locate a COMSPEC environment variable to "
3383 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003384 return FALSE;
3385 }
Tim Peters5aa91602002-01-30 05:46:57 +00003386
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003387 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3388 siStartInfo.cb = sizeof(STARTUPINFO);
3389 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3390 siStartInfo.hStdInput = hStdin;
3391 siStartInfo.hStdOutput = hStdout;
3392 siStartInfo.hStdError = hStderr;
3393 siStartInfo.wShowWindow = SW_HIDE;
3394
3395 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003396 s2,
3397 NULL,
3398 NULL,
3399 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003400 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003401 NULL,
3402 NULL,
3403 &siStartInfo,
3404 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003405 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003406 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003407
Mark Hammondb37a3732000-08-14 04:47:33 +00003408 /* Return process handle */
3409 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003410 return TRUE;
3411 }
Tim Peters402d5982001-08-27 06:37:48 +00003412 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003413 return FALSE;
3414}
3415
3416/* The following code is based off of KB: Q190351 */
3417
3418static PyObject *
3419_PyPopen(char *cmdstring, int mode, int n)
3420{
3421 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3422 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003423 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003424
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003425 SECURITY_ATTRIBUTES saAttr;
3426 BOOL fSuccess;
3427 int fd1, fd2, fd3;
3428 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003429 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003430 PyObject *f;
3431
3432 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3433 saAttr.bInheritHandle = TRUE;
3434 saAttr.lpSecurityDescriptor = NULL;
3435
3436 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3437 return win32_error("CreatePipe", NULL);
3438
3439 /* Create new output read handle and the input write handle. Set
3440 * the inheritance properties to FALSE. Otherwise, the child inherits
3441 * the these handles; resulting in non-closeable handles to the pipes
3442 * being created. */
3443 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003444 GetCurrentProcess(), &hChildStdinWrDup, 0,
3445 FALSE,
3446 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003447 if (!fSuccess)
3448 return win32_error("DuplicateHandle", NULL);
3449
3450 /* Close the inheritable version of ChildStdin
3451 that we're using. */
3452 CloseHandle(hChildStdinWr);
3453
3454 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3455 return win32_error("CreatePipe", NULL);
3456
3457 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003458 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3459 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003460 if (!fSuccess)
3461 return win32_error("DuplicateHandle", NULL);
3462
3463 /* Close the inheritable version of ChildStdout
3464 that we're using. */
3465 CloseHandle(hChildStdoutRd);
3466
3467 if (n != POPEN_4) {
3468 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3469 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003470 fSuccess = DuplicateHandle(GetCurrentProcess(),
3471 hChildStderrRd,
3472 GetCurrentProcess(),
3473 &hChildStderrRdDup, 0,
3474 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003475 if (!fSuccess)
3476 return win32_error("DuplicateHandle", NULL);
3477 /* Close the inheritable version of ChildStdErr that we're using. */
3478 CloseHandle(hChildStderrRd);
3479 }
Tim Peters5aa91602002-01-30 05:46:57 +00003480
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003481 switch (n) {
3482 case POPEN_1:
3483 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3484 case _O_WRONLY | _O_TEXT:
3485 /* Case for writing to child Stdin in text mode. */
3486 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3487 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003488 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003489 PyFile_SetBufSize(f, 0);
3490 /* We don't care about these pipes anymore, so close them. */
3491 CloseHandle(hChildStdoutRdDup);
3492 CloseHandle(hChildStderrRdDup);
3493 break;
3494
3495 case _O_RDONLY | _O_TEXT:
3496 /* Case for reading from child Stdout in text mode. */
3497 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3498 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003499 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003500 PyFile_SetBufSize(f, 0);
3501 /* We don't care about these pipes anymore, so close them. */
3502 CloseHandle(hChildStdinWrDup);
3503 CloseHandle(hChildStderrRdDup);
3504 break;
3505
3506 case _O_RDONLY | _O_BINARY:
3507 /* Case for readinig from child Stdout in binary mode. */
3508 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3509 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003510 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003511 PyFile_SetBufSize(f, 0);
3512 /* We don't care about these pipes anymore, so close them. */
3513 CloseHandle(hChildStdinWrDup);
3514 CloseHandle(hChildStderrRdDup);
3515 break;
3516
3517 case _O_WRONLY | _O_BINARY:
3518 /* Case for writing to child Stdin in binary mode. */
3519 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3520 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003521 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003522 PyFile_SetBufSize(f, 0);
3523 /* We don't care about these pipes anymore, so close them. */
3524 CloseHandle(hChildStdoutRdDup);
3525 CloseHandle(hChildStderrRdDup);
3526 break;
3527 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003528 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003529 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003530
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003531 case POPEN_2:
3532 case POPEN_4:
3533 {
3534 char *m1, *m2;
3535 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003536
Tim Peters7dca21e2002-08-19 00:42:29 +00003537 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003538 m1 = "r";
3539 m2 = "w";
3540 } else {
3541 m1 = "rb";
3542 m2 = "wb";
3543 }
3544
3545 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3546 f1 = _fdopen(fd1, m2);
3547 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3548 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003549 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003550 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003551 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003552 PyFile_SetBufSize(p2, 0);
3553
3554 if (n != 4)
3555 CloseHandle(hChildStderrRdDup);
3556
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003557 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00003558 Py_XDECREF(p1);
3559 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00003560 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003561 break;
3562 }
Tim Peters5aa91602002-01-30 05:46:57 +00003563
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003564 case POPEN_3:
3565 {
3566 char *m1, *m2;
3567 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00003568
Tim Peters7dca21e2002-08-19 00:42:29 +00003569 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003570 m1 = "r";
3571 m2 = "w";
3572 } else {
3573 m1 = "rb";
3574 m2 = "wb";
3575 }
3576
3577 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3578 f1 = _fdopen(fd1, m2);
3579 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3580 f2 = _fdopen(fd2, m1);
3581 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
3582 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003583 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00003584 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
3585 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003586 PyFile_SetBufSize(p1, 0);
3587 PyFile_SetBufSize(p2, 0);
3588 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003589 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00003590 Py_XDECREF(p1);
3591 Py_XDECREF(p2);
3592 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00003593 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003594 break;
3595 }
3596 }
3597
3598 if (n == POPEN_4) {
3599 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003600 hChildStdinRd,
3601 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003602 hChildStdoutWr,
3603 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003604 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003605 }
3606 else {
3607 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003608 hChildStdinRd,
3609 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00003610 hChildStderrWr,
3611 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00003612 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003613 }
3614
Mark Hammondb37a3732000-08-14 04:47:33 +00003615 /*
3616 * Insert the files we've created into the process dictionary
3617 * all referencing the list with the process handle and the
3618 * initial number of files (see description below in _PyPclose).
3619 * Since if _PyPclose later tried to wait on a process when all
3620 * handles weren't closed, it could create a deadlock with the
3621 * child, we spend some energy here to try to ensure that we
3622 * either insert all file handles into the dictionary or none
3623 * at all. It's a little clumsy with the various popen modes
3624 * and variable number of files involved.
3625 */
3626 if (!_PyPopenProcs) {
3627 _PyPopenProcs = PyDict_New();
3628 }
3629
3630 if (_PyPopenProcs) {
3631 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
3632 int ins_rc[3];
3633
3634 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3635 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3636
3637 procObj = PyList_New(2);
3638 hProcessObj = PyLong_FromVoidPtr(hProcess);
3639 intObj = PyInt_FromLong(file_count);
3640
3641 if (procObj && hProcessObj && intObj) {
3642 PyList_SetItem(procObj,0,hProcessObj);
3643 PyList_SetItem(procObj,1,intObj);
3644
3645 fileObj[0] = PyLong_FromVoidPtr(f1);
3646 if (fileObj[0]) {
3647 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3648 fileObj[0],
3649 procObj);
3650 }
3651 if (file_count >= 2) {
3652 fileObj[1] = PyLong_FromVoidPtr(f2);
3653 if (fileObj[1]) {
3654 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3655 fileObj[1],
3656 procObj);
3657 }
3658 }
3659 if (file_count >= 3) {
3660 fileObj[2] = PyLong_FromVoidPtr(f3);
3661 if (fileObj[2]) {
3662 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3663 fileObj[2],
3664 procObj);
3665 }
3666 }
3667
3668 if (ins_rc[0] < 0 || !fileObj[0] ||
3669 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3670 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
3671 /* Something failed - remove any dictionary
3672 * entries that did make it.
3673 */
3674 if (!ins_rc[0] && fileObj[0]) {
3675 PyDict_DelItem(_PyPopenProcs,
3676 fileObj[0]);
3677 }
3678 if (!ins_rc[1] && fileObj[1]) {
3679 PyDict_DelItem(_PyPopenProcs,
3680 fileObj[1]);
3681 }
3682 if (!ins_rc[2] && fileObj[2]) {
3683 PyDict_DelItem(_PyPopenProcs,
3684 fileObj[2]);
3685 }
3686 }
3687 }
Tim Peters5aa91602002-01-30 05:46:57 +00003688
Mark Hammondb37a3732000-08-14 04:47:33 +00003689 /*
3690 * Clean up our localized references for the dictionary keys
3691 * and value since PyDict_SetItem will Py_INCREF any copies
3692 * that got placed in the dictionary.
3693 */
3694 Py_XDECREF(procObj);
3695 Py_XDECREF(fileObj[0]);
3696 Py_XDECREF(fileObj[1]);
3697 Py_XDECREF(fileObj[2]);
3698 }
3699
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003700 /* Child is launched. Close the parents copy of those pipe
3701 * handles that only the child should have open. You need to
3702 * make sure that no handles to the write end of the output pipe
3703 * are maintained in this process or else the pipe will not close
3704 * when the child process exits and the ReadFile will hang. */
3705
3706 if (!CloseHandle(hChildStdinRd))
3707 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003708
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003709 if (!CloseHandle(hChildStdoutWr))
3710 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00003711
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003712 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
3713 return win32_error("CloseHandle", NULL);
3714
3715 return f;
3716}
Fredrik Lundh56055a42000-07-23 19:47:12 +00003717
3718/*
3719 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3720 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00003721 *
3722 * This function uses the _PyPopenProcs dictionary in order to map the
3723 * input file pointer to information about the process that was
3724 * originally created by the popen* call that created the file pointer.
3725 * The dictionary uses the file pointer as a key (with one entry
3726 * inserted for each file returned by the original popen* call) and a
3727 * single list object as the value for all files from a single call.
3728 * The list object contains the Win32 process handle at [0], and a file
3729 * count at [1], which is initialized to the total number of file
3730 * handles using that list.
3731 *
3732 * This function closes whichever handle it is passed, and decrements
3733 * the file count in the dictionary for the process handle pointed to
3734 * by this file. On the last close (when the file count reaches zero),
3735 * this function will wait for the child process and then return its
3736 * exit code as the result of the close() operation. This permits the
3737 * files to be closed in any order - it is always the close() of the
3738 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003739 */
Tim Peters736aa322000-09-01 06:51:24 +00003740
3741 /* RED_FLAG 31-Aug-2000 Tim
3742 * This is always called (today!) between a pair of
3743 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3744 * macros. So the thread running this has no valid thread state, as
3745 * far as Python is concerned. However, this calls some Python API
3746 * functions that cannot be called safely without a valid thread
3747 * state, in particular PyDict_GetItem.
3748 * As a temporary hack (although it may last for years ...), we
3749 * *rely* on not having a valid thread state in this function, in
3750 * order to create our own "from scratch".
3751 * This will deadlock if _PyPclose is ever called by a thread
3752 * holding the global lock.
3753 */
3754
Fredrik Lundh56055a42000-07-23 19:47:12 +00003755static int _PyPclose(FILE *file)
3756{
Fredrik Lundh20318932000-07-26 17:29:12 +00003757 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003758 DWORD exit_code;
3759 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00003760 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
3761 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00003762#ifdef WITH_THREAD
3763 PyInterpreterState* pInterpreterState;
3764 PyThreadState* pThreadState;
3765#endif
3766
Fredrik Lundh20318932000-07-26 17:29:12 +00003767 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00003768 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00003769 */
3770 result = fclose(file);
3771
Tim Peters736aa322000-09-01 06:51:24 +00003772#ifdef WITH_THREAD
3773 /* Bootstrap a valid thread state into existence. */
3774 pInterpreterState = PyInterpreterState_New();
3775 if (!pInterpreterState) {
3776 /* Well, we're hosed now! We don't have a thread
3777 * state, so can't call a nice error routine, or raise
3778 * an exception. Just die.
3779 */
3780 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00003781 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003782 return -1; /* unreachable */
3783 }
3784 pThreadState = PyThreadState_New(pInterpreterState);
3785 if (!pThreadState) {
3786 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00003787 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00003788 return -1; /* unreachable */
3789 }
3790 /* Grab the global lock. Note that this will deadlock if the
3791 * current thread already has the lock! (see RED_FLAG comments
3792 * before this function)
3793 */
3794 PyEval_RestoreThread(pThreadState);
3795#endif
3796
Fredrik Lundh56055a42000-07-23 19:47:12 +00003797 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00003798 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3799 (procObj = PyDict_GetItem(_PyPopenProcs,
3800 fileObj)) != NULL &&
3801 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
3802 (intObj = PyList_GetItem(procObj,1)) != NULL) {
3803
3804 hProcess = PyLong_AsVoidPtr(hProcessObj);
3805 file_count = PyInt_AsLong(intObj);
3806
3807 if (file_count > 1) {
3808 /* Still other files referencing process */
3809 file_count--;
3810 PyList_SetItem(procObj,1,
3811 PyInt_FromLong(file_count));
3812 } else {
3813 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00003814 if (result != EOF &&
3815 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
3816 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00003817 /* Possible truncation here in 16-bit environments, but
3818 * real exit codes are just the lower byte in any event.
3819 */
3820 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003821 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00003822 /* Indicate failure - this will cause the file object
3823 * to raise an I/O error and translate the last Win32
3824 * error code from errno. We do have a problem with
3825 * last errors that overlap the normal errno table,
3826 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003827 */
Fredrik Lundh20318932000-07-26 17:29:12 +00003828 if (result != EOF) {
3829 /* If the error wasn't from the fclose(), then
3830 * set errno for the file object error handling.
3831 */
3832 errno = GetLastError();
3833 }
3834 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00003835 }
3836
3837 /* Free up the native handle at this point */
3838 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00003839 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00003840
Mark Hammondb37a3732000-08-14 04:47:33 +00003841 /* Remove this file pointer from dictionary */
3842 PyDict_DelItem(_PyPopenProcs, fileObj);
3843
3844 if (PyDict_Size(_PyPopenProcs) == 0) {
3845 Py_DECREF(_PyPopenProcs);
3846 _PyPopenProcs = NULL;
3847 }
3848
3849 } /* if object retrieval ok */
3850
3851 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003852 } /* if _PyPopenProcs */
3853
Tim Peters736aa322000-09-01 06:51:24 +00003854#ifdef WITH_THREAD
3855 /* Tear down the thread & interpreter states.
3856 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00003857 * call the thread clear & delete functions, and indeed insist on
3858 * doing that themselves. The lock must be held during the clear, but
3859 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00003860 */
3861 PyInterpreterState_Clear(pInterpreterState);
3862 PyEval_ReleaseThread(pThreadState);
3863 PyInterpreterState_Delete(pInterpreterState);
3864#endif
3865
Fredrik Lundh56055a42000-07-23 19:47:12 +00003866 return result;
3867}
Tim Peters9acdd3a2000-09-01 19:26:36 +00003868
3869#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00003870static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003871posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00003872{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003873 char *name;
3874 char *mode = "r";
3875 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00003876 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00003877 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003878 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00003879 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00003880 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00003881 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00003882 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00003883 if (fp == NULL)
3884 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003885 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003886 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00003887 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00003888 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00003889}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003890
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003891#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003892#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00003893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003894
Guido van Rossumb6775db1994-08-01 11:34:53 +00003895#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003896PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003897"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003898Set the current process's user id.");
3899
Barry Warsaw53699e91996-12-10 23:23:01 +00003900static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003901posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003902{
3903 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003904 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003905 return NULL;
3906 if (setuid(uid) < 0)
3907 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003908 Py_INCREF(Py_None);
3909 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003910}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003911#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00003912
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003913
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003914#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003915PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003916"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003917Set the current process's effective user id.");
3918
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003919static PyObject *
3920posix_seteuid (PyObject *self, PyObject *args)
3921{
3922 int euid;
3923 if (!PyArg_ParseTuple(args, "i", &euid)) {
3924 return NULL;
3925 } else if (seteuid(euid) < 0) {
3926 return posix_error();
3927 } else {
3928 Py_INCREF(Py_None);
3929 return Py_None;
3930 }
3931}
3932#endif /* HAVE_SETEUID */
3933
3934#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003935PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003936"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003937Set the current process's effective group id.");
3938
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003939static PyObject *
3940posix_setegid (PyObject *self, PyObject *args)
3941{
3942 int egid;
3943 if (!PyArg_ParseTuple(args, "i", &egid)) {
3944 return NULL;
3945 } else if (setegid(egid) < 0) {
3946 return posix_error();
3947 } else {
3948 Py_INCREF(Py_None);
3949 return Py_None;
3950 }
3951}
3952#endif /* HAVE_SETEGID */
3953
3954#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003955PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003956"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003957Set the current process's real and effective user ids.");
3958
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003959static PyObject *
3960posix_setreuid (PyObject *self, PyObject *args)
3961{
3962 int ruid, euid;
3963 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
3964 return NULL;
3965 } else if (setreuid(ruid, euid) < 0) {
3966 return posix_error();
3967 } else {
3968 Py_INCREF(Py_None);
3969 return Py_None;
3970 }
3971}
3972#endif /* HAVE_SETREUID */
3973
3974#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003975PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003976"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003977Set the current process's real and effective group ids.");
3978
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00003979static PyObject *
3980posix_setregid (PyObject *self, PyObject *args)
3981{
3982 int rgid, egid;
3983 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
3984 return NULL;
3985 } else if (setregid(rgid, egid) < 0) {
3986 return posix_error();
3987 } else {
3988 Py_INCREF(Py_None);
3989 return Py_None;
3990 }
3991}
3992#endif /* HAVE_SETREGID */
3993
Guido van Rossumb6775db1994-08-01 11:34:53 +00003994#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003995PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003996"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003997Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003998
Barry Warsaw53699e91996-12-10 23:23:01 +00003999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004000posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004001{
4002 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004003 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004004 return NULL;
4005 if (setgid(gid) < 0)
4006 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004007 Py_INCREF(Py_None);
4008 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004009}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004010#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004011
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004012#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004013PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004014"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004015Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004016
4017static PyObject *
4018posix_setgroups(PyObject *self, PyObject *args)
4019{
4020 PyObject *groups;
4021 int i, len;
4022 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004023
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004024 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4025 return NULL;
4026 if (!PySequence_Check(groups)) {
4027 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4028 return NULL;
4029 }
4030 len = PySequence_Size(groups);
4031 if (len > MAX_GROUPS) {
4032 PyErr_SetString(PyExc_ValueError, "too many groups");
4033 return NULL;
4034 }
4035 for(i = 0; i < len; i++) {
4036 PyObject *elem;
4037 elem = PySequence_GetItem(groups, i);
4038 if (!elem)
4039 return NULL;
4040 if (!PyInt_Check(elem)) {
4041 PyErr_SetString(PyExc_TypeError,
4042 "groups must be integers");
4043 Py_DECREF(elem);
4044 return NULL;
4045 }
4046 /* XXX: check that value fits into gid_t. */
4047 grouplist[i] = PyInt_AsLong(elem);
4048 Py_DECREF(elem);
4049 }
4050
4051 if (setgroups(len, grouplist) < 0)
4052 return posix_error();
4053 Py_INCREF(Py_None);
4054 return Py_None;
4055}
4056#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004057
Guido van Rossumb6775db1994-08-01 11:34:53 +00004058#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004059PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004060"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004061Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004062
Barry Warsaw53699e91996-12-10 23:23:01 +00004063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004064posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004065{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004066 int pid, options;
4067#ifdef UNION_WAIT
4068 union wait status;
4069#define status_i (status.w_status)
4070#else
4071 int status;
4072#define status_i status
4073#endif
4074 status_i = 0;
4075
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004076 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004077 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004078 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004079 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004080 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004081 if (pid == -1)
4082 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004083 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004084 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004085}
4086
Tim Petersab034fa2002-02-01 11:27:43 +00004087#elif defined(HAVE_CWAIT)
4088
4089/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004090PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004091"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004092"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004093
4094static PyObject *
4095posix_waitpid(PyObject *self, PyObject *args)
4096{
4097 int pid, options;
4098 int status;
4099
4100 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4101 return NULL;
4102 Py_BEGIN_ALLOW_THREADS
4103 pid = _cwait(&status, pid, options);
4104 Py_END_ALLOW_THREADS
4105 if (pid == -1)
4106 return posix_error();
4107 else
4108 /* shift the status left a byte so this is more like the
4109 POSIX waitpid */
4110 return Py_BuildValue("ii", pid, status << 8);
4111}
4112#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004113
Guido van Rossumad0ee831995-03-01 10:34:45 +00004114#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004115PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004116"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004117Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004118
Barry Warsaw53699e91996-12-10 23:23:01 +00004119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004120posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004121{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004122 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004123#ifdef UNION_WAIT
4124 union wait status;
4125#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004126#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004127 int status;
4128#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004129#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004130 if (!PyArg_ParseTuple(args, ":wait"))
4131 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004132 status_i = 0;
4133 Py_BEGIN_ALLOW_THREADS
4134 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004135 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004136 if (pid == -1)
4137 return posix_error();
4138 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004139 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004140#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004141}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004142#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004145PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004146"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004147Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004148
Barry Warsaw53699e91996-12-10 23:23:01 +00004149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004150posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004151{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004152#ifdef HAVE_LSTAT
Mark Hammondef8b6542001-05-13 08:04:26 +00004153 return posix_do_stat(self, args, "et:lstat", lstat);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004154#else /* !HAVE_LSTAT */
Mark Hammondef8b6542001-05-13 08:04:26 +00004155 return posix_do_stat(self, args, "et:lstat", STAT);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004156#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004157}
4158
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004159
Guido van Rossumb6775db1994-08-01 11:34:53 +00004160#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004161PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004162"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004163Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004164
Barry Warsaw53699e91996-12-10 23:23:01 +00004165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004166posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004167{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004168 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004169 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004170 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004171 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004172 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004173 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004174 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004175 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004176 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004177 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004178 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004179}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004180#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004182
Guido van Rossumb6775db1994-08-01 11:34:53 +00004183#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004184PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004185"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004186Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004187
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004189posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004190{
Mark Hammondef8b6542001-05-13 08:04:26 +00004191 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004192}
4193#endif /* HAVE_SYMLINK */
4194
4195
4196#ifdef HAVE_TIMES
4197#ifndef HZ
4198#define HZ 60 /* Universal constant :-) */
4199#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004200
Guido van Rossumd48f2521997-12-05 22:19:34 +00004201#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4202static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004203system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004204{
4205 ULONG value = 0;
4206
4207 Py_BEGIN_ALLOW_THREADS
4208 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4209 Py_END_ALLOW_THREADS
4210
4211 return value;
4212}
4213
4214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004215posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004216{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004217 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004218 return NULL;
4219
4220 /* Currently Only Uptime is Provided -- Others Later */
4221 return Py_BuildValue("ddddd",
4222 (double)0 /* t.tms_utime / HZ */,
4223 (double)0 /* t.tms_stime / HZ */,
4224 (double)0 /* t.tms_cutime / HZ */,
4225 (double)0 /* t.tms_cstime / HZ */,
4226 (double)system_uptime() / 1000);
4227}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004228#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004230posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004231{
4232 struct tms t;
4233 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004234 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004235 return NULL;
4236 errno = 0;
4237 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004238 if (c == (clock_t) -1)
4239 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004240 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004241 (double)t.tms_utime / HZ,
4242 (double)t.tms_stime / HZ,
4243 (double)t.tms_cutime / HZ,
4244 (double)t.tms_cstime / HZ,
4245 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004246}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004247#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004248#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004249
4250
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004251#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004252#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004253static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004254posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004255{
4256 FILETIME create, exit, kernel, user;
4257 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004258 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004259 return NULL;
4260 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004261 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4262 /* The fields of a FILETIME structure are the hi and lo part
4263 of a 64-bit value expressed in 100 nanosecond units.
4264 1e7 is one second in such units; 1e-7 the inverse.
4265 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4266 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004267 return Py_BuildValue(
4268 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004269 (double)(kernel.dwHighDateTime*429.4967296 +
4270 kernel.dwLowDateTime*1e-7),
4271 (double)(user.dwHighDateTime*429.4967296 +
4272 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004273 (double)0,
4274 (double)0,
4275 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004276}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004277#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004278
4279#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004280PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004281"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004282Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004283#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004284
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004285
Guido van Rossumb6775db1994-08-01 11:34:53 +00004286#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004287PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004288"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004289Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004290
Barry Warsaw53699e91996-12-10 23:23:01 +00004291static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004292posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004293{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004294 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004295 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004296 if (setsid() < 0)
4297 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004298 Py_INCREF(Py_None);
4299 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004300}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004301#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004302
Guido van Rossumb6775db1994-08-01 11:34:53 +00004303#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004304PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004305"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004306Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004307
Barry Warsaw53699e91996-12-10 23:23:01 +00004308static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004309posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004310{
4311 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004312 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004313 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004314 if (setpgid(pid, pgrp) < 0)
4315 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004316 Py_INCREF(Py_None);
4317 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004318}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004319#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004320
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004321
Guido van Rossumb6775db1994-08-01 11:34:53 +00004322#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004323PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004324"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004325Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004326
Barry Warsaw53699e91996-12-10 23:23:01 +00004327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004328posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004329{
4330 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004331 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004332 return NULL;
4333 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004334 if (pgid < 0)
4335 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004336 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004337}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004338#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004340
Guido van Rossumb6775db1994-08-01 11:34:53 +00004341#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004342PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004343"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004344Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004345
Barry Warsaw53699e91996-12-10 23:23:01 +00004346static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004347posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004348{
4349 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004350 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004351 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004352 if (tcsetpgrp(fd, pgid) < 0)
4353 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004354 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004355 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004356}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004357#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004358
Guido van Rossum687dd131993-05-17 08:34:16 +00004359/* Functions acting on file descriptors */
4360
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004361PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004362"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004363Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004364
Barry Warsaw53699e91996-12-10 23:23:01 +00004365static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004366posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004367{
Mark Hammondef8b6542001-05-13 08:04:26 +00004368 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004369 int flag;
4370 int mode = 0777;
4371 int fd;
Tim Peters5aa91602002-01-30 05:46:57 +00004372 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004373 Py_FileSystemDefaultEncoding, &file,
4374 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004375 return NULL;
4376
Barry Warsaw53699e91996-12-10 23:23:01 +00004377 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004378 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004379 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004380 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004381 return posix_error_with_allocated_filename(file);
4382 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004383 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004384}
4385
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004386
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004387PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004388"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004389Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004390
Barry Warsaw53699e91996-12-10 23:23:01 +00004391static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004392posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004393{
4394 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004395 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004396 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004397 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004398 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004399 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004400 if (res < 0)
4401 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004402 Py_INCREF(Py_None);
4403 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004404}
4405
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004406
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004407PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004408"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004409Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004410
Barry Warsaw53699e91996-12-10 23:23:01 +00004411static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004412posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004413{
4414 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004415 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004416 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004417 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004418 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004419 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004420 if (fd < 0)
4421 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004422 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004423}
4424
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004425
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004426PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004427"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004428Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004429
Barry Warsaw53699e91996-12-10 23:23:01 +00004430static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004431posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004432{
4433 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004434 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004435 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004436 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004437 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004438 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004439 if (res < 0)
4440 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004441 Py_INCREF(Py_None);
4442 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004443}
4444
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004445
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004446PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004447"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004448Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004449
Barry Warsaw53699e91996-12-10 23:23:01 +00004450static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004451posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004452{
4453 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004454#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004455 LONG_LONG pos, res;
4456#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004457 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004458#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004459 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004460 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004461 return NULL;
4462#ifdef SEEK_SET
4463 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4464 switch (how) {
4465 case 0: how = SEEK_SET; break;
4466 case 1: how = SEEK_CUR; break;
4467 case 2: how = SEEK_END; break;
4468 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004469#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004470
4471#if !defined(HAVE_LARGEFILE_SUPPORT)
4472 pos = PyInt_AsLong(posobj);
4473#else
4474 pos = PyLong_Check(posobj) ?
4475 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4476#endif
4477 if (PyErr_Occurred())
4478 return NULL;
4479
Barry Warsaw53699e91996-12-10 23:23:01 +00004480 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004481#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004482 res = _lseeki64(fd, pos, how);
4483#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004484 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004485#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004486 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004487 if (res < 0)
4488 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004489
4490#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004491 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004492#else
4493 return PyLong_FromLongLong(res);
4494#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004495}
4496
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004497
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004498PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004499"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004500Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004501
Barry Warsaw53699e91996-12-10 23:23:01 +00004502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004503posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004504{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004505 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004506 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004507 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004508 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004509 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004510 if (buffer == NULL)
4511 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004512 Py_BEGIN_ALLOW_THREADS
4513 n = read(fd, PyString_AsString(buffer), size);
4514 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004515 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004516 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004517 return posix_error();
4518 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004519 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004520 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004521 return buffer;
4522}
4523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004524
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004525PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004526"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004527Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004528
Barry Warsaw53699e91996-12-10 23:23:01 +00004529static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004530posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004531{
4532 int fd, size;
4533 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004534 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004535 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004536 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004537 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00004538 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004539 if (size < 0)
4540 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004541 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004542}
4543
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004544
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004545PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004546"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004547Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004548
Barry Warsaw53699e91996-12-10 23:23:01 +00004549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004550posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004551{
4552 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00004553 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00004554 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004555 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004556 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004557 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00004558 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00004559 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004560 if (res != 0)
4561 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00004562
Fred Drake699f3522000-06-29 21:12:41 +00004563 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00004564}
4565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004566
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004567PyDoc_STRVAR(posix_fdopen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004568"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004569Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004570
Barry Warsaw53699e91996-12-10 23:23:01 +00004571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004572posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004573{
Guido van Rossum687dd131993-05-17 08:34:16 +00004574 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004575 char *mode = "r";
4576 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00004577 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004578 PyObject *f;
4579 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00004580 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00004581
Barry Warsaw53699e91996-12-10 23:23:01 +00004582 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004583 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004584 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004585 if (fp == NULL)
4586 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00004587 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004588 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004589 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004590 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00004591}
4592
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004593PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004594"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004595Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004596connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00004597
4598static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00004599posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00004600{
4601 int fd;
4602 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
4603 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00004604 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00004605}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004606
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004607#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004608PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004609"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004610Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004611
Barry Warsaw53699e91996-12-10 23:23:01 +00004612static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004613posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004614{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004615#if defined(PYOS_OS2)
4616 HFILE read, write;
4617 APIRET rc;
4618
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004619 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004620 return NULL;
4621
4622 Py_BEGIN_ALLOW_THREADS
4623 rc = DosCreatePipe( &read, &write, 4096);
4624 Py_END_ALLOW_THREADS
4625 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004626 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004627
4628 return Py_BuildValue("(ii)", read, write);
4629#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004630#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00004631 int fds[2];
4632 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004633 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00004634 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004635 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004636 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00004637 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004638 if (res != 0)
4639 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004640 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004641#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00004642 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004643 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00004644 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004645 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00004646 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004647 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004648 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00004649 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00004650 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004651 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00004652 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
4653 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00004654 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004655#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004656#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004657}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004658#endif /* HAVE_PIPE */
4659
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004660
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004661#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004662PyDoc_STRVAR(posix_mkfifo__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004663"mkfifo(filename, [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004664Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004665
Barry Warsaw53699e91996-12-10 23:23:01 +00004666static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004667posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004668{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004669 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004670 int mode = 0666;
4671 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004672 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004673 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004674 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004675 res = mkfifo(filename, mode);
4676 Py_END_ALLOW_THREADS
4677 if (res < 0)
4678 return posix_error();
4679 Py_INCREF(Py_None);
4680 return Py_None;
4681}
4682#endif
4683
4684
Neal Norwitz11690112002-07-30 01:08:28 +00004685#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004686PyDoc_STRVAR(posix_mknod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004687"mknod(filename, [, mode=0600, major, minor])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004688Create a filesystem node (file, device special file or named pipe)\n\
4689named filename. mode specifies both the permissions to use and the\n\
4690type of node to be created, being combined (bitwise OR) with one of\n\
4691S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
4692major and minor define the newly created device special file, otherwise\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004693they are ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00004694
4695
4696static PyObject *
4697posix_mknod(PyObject *self, PyObject *args)
4698{
4699 char *filename;
4700 int mode = 0600;
4701 int major = 0;
4702 int minor = 0;
4703 int res;
4704 if (!PyArg_ParseTuple(args, "s|iii:mknod", &filename,
4705 &mode, &major, &minor))
4706 return NULL;
4707 Py_BEGIN_ALLOW_THREADS
4708 res = mknod(filename, mode, makedev(major, minor));
Barry Warsaw53699e91996-12-10 23:23:01 +00004709 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004710 if (res < 0)
4711 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004712 Py_INCREF(Py_None);
4713 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004714}
4715#endif
4716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004717
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004718#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004719PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004720"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004721Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004722
Barry Warsaw53699e91996-12-10 23:23:01 +00004723static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004724posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004725{
4726 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004727 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004728 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00004729 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004730
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004731 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00004732 return NULL;
4733
4734#if !defined(HAVE_LARGEFILE_SUPPORT)
4735 length = PyInt_AsLong(lenobj);
4736#else
4737 length = PyLong_Check(lenobj) ?
4738 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
4739#endif
4740 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004741 return NULL;
4742
Barry Warsaw53699e91996-12-10 23:23:01 +00004743 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004744 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00004745 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004746 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004747 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004748 return NULL;
4749 }
Barry Warsaw53699e91996-12-10 23:23:01 +00004750 Py_INCREF(Py_None);
4751 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004752}
4753#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004754
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004755#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004756PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004757"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004758Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004759
Fred Drake762e2061999-08-26 17:23:54 +00004760/* Save putenv() parameters as values here, so we can collect them when they
4761 * get re-set with another call for the same key. */
4762static PyObject *posix_putenv_garbage;
4763
Tim Peters5aa91602002-01-30 05:46:57 +00004764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004765posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004766{
4767 char *s1, *s2;
4768 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00004769 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00004770 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004771
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004772 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004773 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00004774
4775#if defined(PYOS_OS2)
4776 if (stricmp(s1, "BEGINLIBPATH") == 0) {
4777 APIRET rc;
4778
4779 if (strlen(s2) == 0) /* If New Value is an Empty String */
4780 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4781
4782 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
4783 if (rc != NO_ERROR)
4784 return os2_error(rc);
4785
4786 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
4787 APIRET rc;
4788
4789 if (strlen(s2) == 0) /* If New Value is an Empty String */
4790 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
4791
4792 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
4793 if (rc != NO_ERROR)
4794 return os2_error(rc);
4795 } else {
4796#endif
4797
Fred Drake762e2061999-08-26 17:23:54 +00004798 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00004799 len = strlen(s1) + strlen(s2) + 2;
4800 /* len includes space for a trailing \0; the size arg to
4801 PyString_FromStringAndSize does not count that */
4802 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00004803 if (newstr == NULL)
4804 return PyErr_NoMemory();
4805 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00004806 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004807 if (putenv(new)) {
4808 posix_error();
4809 return NULL;
4810 }
Fred Drake762e2061999-08-26 17:23:54 +00004811 /* Install the first arg and newstr in posix_putenv_garbage;
4812 * this will cause previous value to be collected. This has to
4813 * happen after the real putenv() call because the old value
4814 * was still accessible until then. */
4815 if (PyDict_SetItem(posix_putenv_garbage,
4816 PyTuple_GET_ITEM(args, 0), newstr)) {
4817 /* really not much we can do; just leak */
4818 PyErr_Clear();
4819 }
4820 else {
4821 Py_DECREF(newstr);
4822 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00004823
4824#if defined(PYOS_OS2)
4825 }
4826#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004827 Py_INCREF(Py_None);
4828 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004829}
Guido van Rossumb6a47161997-09-15 22:54:34 +00004830#endif /* putenv */
4831
Guido van Rossumc524d952001-10-19 01:31:59 +00004832#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004833PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004834"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004835Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00004836
4837static PyObject *
4838posix_unsetenv(PyObject *self, PyObject *args)
4839{
4840 char *s1;
4841
4842 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
4843 return NULL;
4844
4845 unsetenv(s1);
4846
4847 /* Remove the key from posix_putenv_garbage;
4848 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00004849 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00004850 * old value was still accessible until then.
4851 */
4852 if (PyDict_DelItem(posix_putenv_garbage,
4853 PyTuple_GET_ITEM(args, 0))) {
4854 /* really not much we can do; just leak */
4855 PyErr_Clear();
4856 }
4857
4858 Py_INCREF(Py_None);
4859 return Py_None;
4860}
4861#endif /* unsetenv */
4862
Guido van Rossumb6a47161997-09-15 22:54:34 +00004863#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004864PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004865"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004866Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004867
Guido van Rossumf68d8e52001-04-14 17:55:09 +00004868static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004869posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00004870{
4871 int code;
4872 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004873 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00004874 return NULL;
4875 message = strerror(code);
4876 if (message == NULL) {
4877 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00004878 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00004879 return NULL;
4880 }
4881 return PyString_FromString(message);
4882}
4883#endif /* strerror */
4884
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00004885
Guido van Rossumc9641791998-08-04 15:26:23 +00004886#ifdef HAVE_SYS_WAIT_H
4887
Fred Drake106c1a02002-04-23 15:58:02 +00004888#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004889PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004890"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004891Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00004892
4893static PyObject *
4894posix_WCOREDUMP(PyObject *self, PyObject *args)
4895{
4896#ifdef UNION_WAIT
4897 union wait status;
4898#define status_i (status.w_status)
4899#else
4900 int status;
4901#define status_i status
4902#endif
4903 status_i = 0;
4904
4905 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
4906 {
4907 return NULL;
4908 }
4909
4910 return PyBool_FromLong(WCOREDUMP(status));
4911#undef status_i
4912}
4913#endif /* WCOREDUMP */
4914
4915#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004916PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004917"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00004918Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004919job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00004920
4921static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004922posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00004923{
4924#ifdef UNION_WAIT
4925 union wait status;
4926#define status_i (status.w_status)
4927#else
4928 int status;
4929#define status_i status
4930#endif
4931 status_i = 0;
4932
4933 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
4934 {
4935 return NULL;
4936 }
4937
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00004938 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00004939#undef status_i
4940}
4941#endif /* WIFCONTINUED */
4942
Guido van Rossumc9641791998-08-04 15:26:23 +00004943#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004944PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004945"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004946Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004947
4948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004949posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004950{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004951#ifdef UNION_WAIT
4952 union wait status;
4953#define status_i (status.w_status)
4954#else
4955 int status;
4956#define status_i status
4957#endif
4958 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004959
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004960 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004961 {
4962 return NULL;
4963 }
Tim Peters5aa91602002-01-30 05:46:57 +00004964
Fred Drake106c1a02002-04-23 15:58:02 +00004965 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004966#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004967}
4968#endif /* WIFSTOPPED */
4969
4970#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004971PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004972"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004973Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00004974
4975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004976posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00004977{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004978#ifdef UNION_WAIT
4979 union wait status;
4980#define status_i (status.w_status)
4981#else
4982 int status;
4983#define status_i status
4984#endif
4985 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004986
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004987 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00004988 {
4989 return NULL;
4990 }
Tim Peters5aa91602002-01-30 05:46:57 +00004991
Fred Drake106c1a02002-04-23 15:58:02 +00004992 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004993#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00004994}
4995#endif /* WIFSIGNALED */
4996
4997#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004998PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004999"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005000Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005001system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005002
5003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005004posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005005{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005006#ifdef UNION_WAIT
5007 union wait status;
5008#define status_i (status.w_status)
5009#else
5010 int status;
5011#define status_i status
5012#endif
5013 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005014
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005015 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005016 {
5017 return NULL;
5018 }
Tim Peters5aa91602002-01-30 05:46:57 +00005019
Fred Drake106c1a02002-04-23 15:58:02 +00005020 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005021#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005022}
5023#endif /* WIFEXITED */
5024
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005025#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005026PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005027"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005028Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005029
5030static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005031posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005032{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005033#ifdef UNION_WAIT
5034 union wait status;
5035#define status_i (status.w_status)
5036#else
5037 int status;
5038#define status_i status
5039#endif
5040 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005041
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005042 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005043 {
5044 return NULL;
5045 }
Tim Peters5aa91602002-01-30 05:46:57 +00005046
Guido van Rossumc9641791998-08-04 15:26:23 +00005047 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005048#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005049}
5050#endif /* WEXITSTATUS */
5051
5052#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005053PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005054"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005055Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005056value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005057
5058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005059posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005060{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005061#ifdef UNION_WAIT
5062 union wait status;
5063#define status_i (status.w_status)
5064#else
5065 int status;
5066#define status_i status
5067#endif
5068 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005069
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005070 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005071 {
5072 return NULL;
5073 }
Tim Peters5aa91602002-01-30 05:46:57 +00005074
Guido van Rossumc9641791998-08-04 15:26:23 +00005075 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005076#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005077}
5078#endif /* WTERMSIG */
5079
5080#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005081PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005082"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005083Return the signal that stopped the process that provided\n\
5084the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005085
5086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005087posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005088{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005089#ifdef UNION_WAIT
5090 union wait status;
5091#define status_i (status.w_status)
5092#else
5093 int status;
5094#define status_i status
5095#endif
5096 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005097
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005098 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005099 {
5100 return NULL;
5101 }
Tim Peters5aa91602002-01-30 05:46:57 +00005102
Guido van Rossumc9641791998-08-04 15:26:23 +00005103 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005104#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005105}
5106#endif /* WSTOPSIG */
5107
5108#endif /* HAVE_SYS_WAIT_H */
5109
5110
Guido van Rossum94f6f721999-01-06 18:42:14 +00005111#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005112#ifdef _SCO_DS
5113/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5114 needed definitions in sys/statvfs.h */
5115#define _SVID3
5116#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005117#include <sys/statvfs.h>
5118
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005119static PyObject*
5120_pystatvfs_fromstructstatvfs(struct statvfs st) {
5121 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5122 if (v == NULL)
5123 return NULL;
5124
5125#if !defined(HAVE_LARGEFILE_SUPPORT)
5126 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5127 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5128 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5129 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5130 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5131 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5132 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5133 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5134 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5135 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5136#else
5137 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5138 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005139 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005140 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005141 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005142 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5143 PyStructSequence_SET_ITEM(v, 4,
5144 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005145 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005146 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005147 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005148 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005149 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005150 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5151 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5152 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5153#endif
5154
5155 return v;
5156}
5157
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005158PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005159"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005160Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005161
5162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005163posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005164{
5165 int fd, res;
5166 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005167
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005168 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005169 return NULL;
5170 Py_BEGIN_ALLOW_THREADS
5171 res = fstatvfs(fd, &st);
5172 Py_END_ALLOW_THREADS
5173 if (res != 0)
5174 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005175
5176 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005177}
5178#endif /* HAVE_FSTATVFS */
5179
5180
5181#if defined(HAVE_STATVFS)
5182#include <sys/statvfs.h>
5183
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005184PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005185"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005186Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005187
5188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005189posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005190{
5191 char *path;
5192 int res;
5193 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005194 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005195 return NULL;
5196 Py_BEGIN_ALLOW_THREADS
5197 res = statvfs(path, &st);
5198 Py_END_ALLOW_THREADS
5199 if (res != 0)
5200 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005201
5202 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005203}
5204#endif /* HAVE_STATVFS */
5205
5206
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005207#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005208PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005209"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005210Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005211The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005212or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005213
5214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005215posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005216{
5217 PyObject *result = NULL;
5218 char *dir = NULL;
5219 char *pfx = NULL;
5220 char *name;
5221
5222 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5223 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005224
5225 if (PyErr_Warn(PyExc_RuntimeWarning,
5226 "tempnam is a potential security risk to your program") < 0)
5227 return NULL;
5228
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005229#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005230 name = _tempnam(dir, pfx);
5231#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005232 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005233#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005234 if (name == NULL)
5235 return PyErr_NoMemory();
5236 result = PyString_FromString(name);
5237 free(name);
5238 return result;
5239}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005240#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005241
5242
5243#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005244PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005245"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005246Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005247
5248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005249posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005250{
5251 FILE *fp;
5252
5253 if (!PyArg_ParseTuple(args, ":tmpfile"))
5254 return NULL;
5255 fp = tmpfile();
5256 if (fp == NULL)
5257 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005258 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005259}
5260#endif
5261
5262
5263#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005264PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005265"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005266Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005267
5268static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005269posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005270{
5271 char buffer[L_tmpnam];
5272 char *name;
5273
5274 if (!PyArg_ParseTuple(args, ":tmpnam"))
5275 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005276
5277 if (PyErr_Warn(PyExc_RuntimeWarning,
5278 "tmpnam is a potential security risk to your program") < 0)
5279 return NULL;
5280
Greg Wardb48bc172000-03-01 21:51:56 +00005281#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005282 name = tmpnam_r(buffer);
5283#else
5284 name = tmpnam(buffer);
5285#endif
5286 if (name == NULL) {
5287 PyErr_SetObject(PyExc_OSError,
5288 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005289#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005290 "unexpected NULL from tmpnam_r"
5291#else
5292 "unexpected NULL from tmpnam"
5293#endif
5294 ));
5295 return NULL;
5296 }
5297 return PyString_FromString(buffer);
5298}
5299#endif
5300
5301
Fred Drakec9680921999-12-13 16:37:25 +00005302/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5303 * It maps strings representing configuration variable names to
5304 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005305 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005306 * rarely-used constants. There are three separate tables that use
5307 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005308 *
5309 * This code is always included, even if none of the interfaces that
5310 * need it are included. The #if hackery needed to avoid it would be
5311 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005312 */
5313struct constdef {
5314 char *name;
5315 long value;
5316};
5317
Fred Drake12c6e2d1999-12-14 21:25:03 +00005318static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005319conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5320 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005321{
5322 if (PyInt_Check(arg)) {
5323 *valuep = PyInt_AS_LONG(arg);
5324 return 1;
5325 }
5326 if (PyString_Check(arg)) {
5327 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005328 size_t lo = 0;
5329 size_t mid;
5330 size_t hi = tablesize;
5331 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005332 char *confname = PyString_AS_STRING(arg);
5333 while (lo < hi) {
5334 mid = (lo + hi) / 2;
5335 cmp = strcmp(confname, table[mid].name);
5336 if (cmp < 0)
5337 hi = mid;
5338 else if (cmp > 0)
5339 lo = mid + 1;
5340 else {
5341 *valuep = table[mid].value;
5342 return 1;
5343 }
5344 }
5345 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5346 }
5347 else
5348 PyErr_SetString(PyExc_TypeError,
5349 "configuration names must be strings or integers");
5350 return 0;
5351}
5352
5353
5354#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5355static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005356#ifdef _PC_ABI_AIO_XFER_MAX
5357 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5358#endif
5359#ifdef _PC_ABI_ASYNC_IO
5360 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5361#endif
Fred Drakec9680921999-12-13 16:37:25 +00005362#ifdef _PC_ASYNC_IO
5363 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5364#endif
5365#ifdef _PC_CHOWN_RESTRICTED
5366 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5367#endif
5368#ifdef _PC_FILESIZEBITS
5369 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5370#endif
5371#ifdef _PC_LAST
5372 {"PC_LAST", _PC_LAST},
5373#endif
5374#ifdef _PC_LINK_MAX
5375 {"PC_LINK_MAX", _PC_LINK_MAX},
5376#endif
5377#ifdef _PC_MAX_CANON
5378 {"PC_MAX_CANON", _PC_MAX_CANON},
5379#endif
5380#ifdef _PC_MAX_INPUT
5381 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5382#endif
5383#ifdef _PC_NAME_MAX
5384 {"PC_NAME_MAX", _PC_NAME_MAX},
5385#endif
5386#ifdef _PC_NO_TRUNC
5387 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5388#endif
5389#ifdef _PC_PATH_MAX
5390 {"PC_PATH_MAX", _PC_PATH_MAX},
5391#endif
5392#ifdef _PC_PIPE_BUF
5393 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5394#endif
5395#ifdef _PC_PRIO_IO
5396 {"PC_PRIO_IO", _PC_PRIO_IO},
5397#endif
5398#ifdef _PC_SOCK_MAXBUF
5399 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5400#endif
5401#ifdef _PC_SYNC_IO
5402 {"PC_SYNC_IO", _PC_SYNC_IO},
5403#endif
5404#ifdef _PC_VDISABLE
5405 {"PC_VDISABLE", _PC_VDISABLE},
5406#endif
5407};
5408
Fred Drakec9680921999-12-13 16:37:25 +00005409static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005410conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005411{
5412 return conv_confname(arg, valuep, posix_constants_pathconf,
5413 sizeof(posix_constants_pathconf)
5414 / sizeof(struct constdef));
5415}
5416#endif
5417
5418#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005419PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005420"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005421Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005422If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005423
5424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005425posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005426{
5427 PyObject *result = NULL;
5428 int name, fd;
5429
Fred Drake12c6e2d1999-12-14 21:25:03 +00005430 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5431 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005432 long limit;
5433
5434 errno = 0;
5435 limit = fpathconf(fd, name);
5436 if (limit == -1 && errno != 0)
5437 posix_error();
5438 else
5439 result = PyInt_FromLong(limit);
5440 }
5441 return result;
5442}
5443#endif
5444
5445
5446#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005447PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005448"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005449Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005450If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005451
5452static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005453posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005454{
5455 PyObject *result = NULL;
5456 int name;
5457 char *path;
5458
5459 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5460 conv_path_confname, &name)) {
5461 long limit;
5462
5463 errno = 0;
5464 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005465 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005466 if (errno == EINVAL)
5467 /* could be a path or name problem */
5468 posix_error();
5469 else
5470 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005471 }
Fred Drakec9680921999-12-13 16:37:25 +00005472 else
5473 result = PyInt_FromLong(limit);
5474 }
5475 return result;
5476}
5477#endif
5478
5479#ifdef HAVE_CONFSTR
5480static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005481#ifdef _CS_ARCHITECTURE
5482 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5483#endif
5484#ifdef _CS_HOSTNAME
5485 {"CS_HOSTNAME", _CS_HOSTNAME},
5486#endif
5487#ifdef _CS_HW_PROVIDER
5488 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
5489#endif
5490#ifdef _CS_HW_SERIAL
5491 {"CS_HW_SERIAL", _CS_HW_SERIAL},
5492#endif
5493#ifdef _CS_INITTAB_NAME
5494 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
5495#endif
Fred Drakec9680921999-12-13 16:37:25 +00005496#ifdef _CS_LFS64_CFLAGS
5497 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
5498#endif
5499#ifdef _CS_LFS64_LDFLAGS
5500 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
5501#endif
5502#ifdef _CS_LFS64_LIBS
5503 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
5504#endif
5505#ifdef _CS_LFS64_LINTFLAGS
5506 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
5507#endif
5508#ifdef _CS_LFS_CFLAGS
5509 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
5510#endif
5511#ifdef _CS_LFS_LDFLAGS
5512 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
5513#endif
5514#ifdef _CS_LFS_LIBS
5515 {"CS_LFS_LIBS", _CS_LFS_LIBS},
5516#endif
5517#ifdef _CS_LFS_LINTFLAGS
5518 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
5519#endif
Fred Draked86ed291999-12-15 15:34:33 +00005520#ifdef _CS_MACHINE
5521 {"CS_MACHINE", _CS_MACHINE},
5522#endif
Fred Drakec9680921999-12-13 16:37:25 +00005523#ifdef _CS_PATH
5524 {"CS_PATH", _CS_PATH},
5525#endif
Fred Draked86ed291999-12-15 15:34:33 +00005526#ifdef _CS_RELEASE
5527 {"CS_RELEASE", _CS_RELEASE},
5528#endif
5529#ifdef _CS_SRPC_DOMAIN
5530 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
5531#endif
5532#ifdef _CS_SYSNAME
5533 {"CS_SYSNAME", _CS_SYSNAME},
5534#endif
5535#ifdef _CS_VERSION
5536 {"CS_VERSION", _CS_VERSION},
5537#endif
Fred Drakec9680921999-12-13 16:37:25 +00005538#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
5539 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
5540#endif
5541#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
5542 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
5543#endif
5544#ifdef _CS_XBS5_ILP32_OFF32_LIBS
5545 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
5546#endif
5547#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
5548 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
5549#endif
5550#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
5551 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
5552#endif
5553#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
5554 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
5555#endif
5556#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
5557 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
5558#endif
5559#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
5560 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
5561#endif
5562#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
5563 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
5564#endif
5565#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
5566 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
5567#endif
5568#ifdef _CS_XBS5_LP64_OFF64_LIBS
5569 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
5570#endif
5571#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
5572 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
5573#endif
5574#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
5575 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
5576#endif
5577#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
5578 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
5579#endif
5580#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
5581 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
5582#endif
5583#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
5584 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
5585#endif
Fred Draked86ed291999-12-15 15:34:33 +00005586#ifdef _MIPS_CS_AVAIL_PROCESSORS
5587 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
5588#endif
5589#ifdef _MIPS_CS_BASE
5590 {"MIPS_CS_BASE", _MIPS_CS_BASE},
5591#endif
5592#ifdef _MIPS_CS_HOSTID
5593 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
5594#endif
5595#ifdef _MIPS_CS_HW_NAME
5596 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
5597#endif
5598#ifdef _MIPS_CS_NUM_PROCESSORS
5599 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
5600#endif
5601#ifdef _MIPS_CS_OSREL_MAJ
5602 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
5603#endif
5604#ifdef _MIPS_CS_OSREL_MIN
5605 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
5606#endif
5607#ifdef _MIPS_CS_OSREL_PATCH
5608 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
5609#endif
5610#ifdef _MIPS_CS_OS_NAME
5611 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
5612#endif
5613#ifdef _MIPS_CS_OS_PROVIDER
5614 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
5615#endif
5616#ifdef _MIPS_CS_PROCESSORS
5617 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
5618#endif
5619#ifdef _MIPS_CS_SERIAL
5620 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
5621#endif
5622#ifdef _MIPS_CS_VENDOR
5623 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
5624#endif
Fred Drakec9680921999-12-13 16:37:25 +00005625};
5626
5627static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005628conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005629{
5630 return conv_confname(arg, valuep, posix_constants_confstr,
5631 sizeof(posix_constants_confstr)
5632 / sizeof(struct constdef));
5633}
5634
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005635PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005636"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005637Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00005638
5639static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005640posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005641{
5642 PyObject *result = NULL;
5643 int name;
5644 char buffer[64];
5645
5646 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
5647 int len = confstr(name, buffer, sizeof(buffer));
5648
Fred Drakec9680921999-12-13 16:37:25 +00005649 errno = 0;
5650 if (len == 0) {
5651 if (errno != 0)
5652 posix_error();
5653 else
5654 result = PyString_FromString("");
5655 }
5656 else {
5657 if (len >= sizeof(buffer)) {
5658 result = PyString_FromStringAndSize(NULL, len);
5659 if (result != NULL)
5660 confstr(name, PyString_AS_STRING(result), len+1);
5661 }
5662 else
5663 result = PyString_FromString(buffer);
5664 }
5665 }
5666 return result;
5667}
5668#endif
5669
5670
5671#ifdef HAVE_SYSCONF
5672static struct constdef posix_constants_sysconf[] = {
5673#ifdef _SC_2_CHAR_TERM
5674 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
5675#endif
5676#ifdef _SC_2_C_BIND
5677 {"SC_2_C_BIND", _SC_2_C_BIND},
5678#endif
5679#ifdef _SC_2_C_DEV
5680 {"SC_2_C_DEV", _SC_2_C_DEV},
5681#endif
5682#ifdef _SC_2_C_VERSION
5683 {"SC_2_C_VERSION", _SC_2_C_VERSION},
5684#endif
5685#ifdef _SC_2_FORT_DEV
5686 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
5687#endif
5688#ifdef _SC_2_FORT_RUN
5689 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
5690#endif
5691#ifdef _SC_2_LOCALEDEF
5692 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
5693#endif
5694#ifdef _SC_2_SW_DEV
5695 {"SC_2_SW_DEV", _SC_2_SW_DEV},
5696#endif
5697#ifdef _SC_2_UPE
5698 {"SC_2_UPE", _SC_2_UPE},
5699#endif
5700#ifdef _SC_2_VERSION
5701 {"SC_2_VERSION", _SC_2_VERSION},
5702#endif
Fred Draked86ed291999-12-15 15:34:33 +00005703#ifdef _SC_ABI_ASYNCHRONOUS_IO
5704 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
5705#endif
5706#ifdef _SC_ACL
5707 {"SC_ACL", _SC_ACL},
5708#endif
Fred Drakec9680921999-12-13 16:37:25 +00005709#ifdef _SC_AIO_LISTIO_MAX
5710 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
5711#endif
Fred Drakec9680921999-12-13 16:37:25 +00005712#ifdef _SC_AIO_MAX
5713 {"SC_AIO_MAX", _SC_AIO_MAX},
5714#endif
5715#ifdef _SC_AIO_PRIO_DELTA_MAX
5716 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
5717#endif
5718#ifdef _SC_ARG_MAX
5719 {"SC_ARG_MAX", _SC_ARG_MAX},
5720#endif
5721#ifdef _SC_ASYNCHRONOUS_IO
5722 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
5723#endif
5724#ifdef _SC_ATEXIT_MAX
5725 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
5726#endif
Fred Draked86ed291999-12-15 15:34:33 +00005727#ifdef _SC_AUDIT
5728 {"SC_AUDIT", _SC_AUDIT},
5729#endif
Fred Drakec9680921999-12-13 16:37:25 +00005730#ifdef _SC_AVPHYS_PAGES
5731 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
5732#endif
5733#ifdef _SC_BC_BASE_MAX
5734 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
5735#endif
5736#ifdef _SC_BC_DIM_MAX
5737 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
5738#endif
5739#ifdef _SC_BC_SCALE_MAX
5740 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
5741#endif
5742#ifdef _SC_BC_STRING_MAX
5743 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
5744#endif
Fred Draked86ed291999-12-15 15:34:33 +00005745#ifdef _SC_CAP
5746 {"SC_CAP", _SC_CAP},
5747#endif
Fred Drakec9680921999-12-13 16:37:25 +00005748#ifdef _SC_CHARCLASS_NAME_MAX
5749 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
5750#endif
5751#ifdef _SC_CHAR_BIT
5752 {"SC_CHAR_BIT", _SC_CHAR_BIT},
5753#endif
5754#ifdef _SC_CHAR_MAX
5755 {"SC_CHAR_MAX", _SC_CHAR_MAX},
5756#endif
5757#ifdef _SC_CHAR_MIN
5758 {"SC_CHAR_MIN", _SC_CHAR_MIN},
5759#endif
5760#ifdef _SC_CHILD_MAX
5761 {"SC_CHILD_MAX", _SC_CHILD_MAX},
5762#endif
5763#ifdef _SC_CLK_TCK
5764 {"SC_CLK_TCK", _SC_CLK_TCK},
5765#endif
5766#ifdef _SC_COHER_BLKSZ
5767 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
5768#endif
5769#ifdef _SC_COLL_WEIGHTS_MAX
5770 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
5771#endif
5772#ifdef _SC_DCACHE_ASSOC
5773 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
5774#endif
5775#ifdef _SC_DCACHE_BLKSZ
5776 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
5777#endif
5778#ifdef _SC_DCACHE_LINESZ
5779 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
5780#endif
5781#ifdef _SC_DCACHE_SZ
5782 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
5783#endif
5784#ifdef _SC_DCACHE_TBLKSZ
5785 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
5786#endif
5787#ifdef _SC_DELAYTIMER_MAX
5788 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
5789#endif
5790#ifdef _SC_EQUIV_CLASS_MAX
5791 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
5792#endif
5793#ifdef _SC_EXPR_NEST_MAX
5794 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
5795#endif
5796#ifdef _SC_FSYNC
5797 {"SC_FSYNC", _SC_FSYNC},
5798#endif
5799#ifdef _SC_GETGR_R_SIZE_MAX
5800 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
5801#endif
5802#ifdef _SC_GETPW_R_SIZE_MAX
5803 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
5804#endif
5805#ifdef _SC_ICACHE_ASSOC
5806 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
5807#endif
5808#ifdef _SC_ICACHE_BLKSZ
5809 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
5810#endif
5811#ifdef _SC_ICACHE_LINESZ
5812 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
5813#endif
5814#ifdef _SC_ICACHE_SZ
5815 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
5816#endif
Fred Draked86ed291999-12-15 15:34:33 +00005817#ifdef _SC_INF
5818 {"SC_INF", _SC_INF},
5819#endif
Fred Drakec9680921999-12-13 16:37:25 +00005820#ifdef _SC_INT_MAX
5821 {"SC_INT_MAX", _SC_INT_MAX},
5822#endif
5823#ifdef _SC_INT_MIN
5824 {"SC_INT_MIN", _SC_INT_MIN},
5825#endif
5826#ifdef _SC_IOV_MAX
5827 {"SC_IOV_MAX", _SC_IOV_MAX},
5828#endif
Fred Draked86ed291999-12-15 15:34:33 +00005829#ifdef _SC_IP_SECOPTS
5830 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
5831#endif
Fred Drakec9680921999-12-13 16:37:25 +00005832#ifdef _SC_JOB_CONTROL
5833 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
5834#endif
Fred Draked86ed291999-12-15 15:34:33 +00005835#ifdef _SC_KERN_POINTERS
5836 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
5837#endif
5838#ifdef _SC_KERN_SIM
5839 {"SC_KERN_SIM", _SC_KERN_SIM},
5840#endif
Fred Drakec9680921999-12-13 16:37:25 +00005841#ifdef _SC_LINE_MAX
5842 {"SC_LINE_MAX", _SC_LINE_MAX},
5843#endif
5844#ifdef _SC_LOGIN_NAME_MAX
5845 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
5846#endif
5847#ifdef _SC_LOGNAME_MAX
5848 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
5849#endif
5850#ifdef _SC_LONG_BIT
5851 {"SC_LONG_BIT", _SC_LONG_BIT},
5852#endif
Fred Draked86ed291999-12-15 15:34:33 +00005853#ifdef _SC_MAC
5854 {"SC_MAC", _SC_MAC},
5855#endif
Fred Drakec9680921999-12-13 16:37:25 +00005856#ifdef _SC_MAPPED_FILES
5857 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
5858#endif
5859#ifdef _SC_MAXPID
5860 {"SC_MAXPID", _SC_MAXPID},
5861#endif
5862#ifdef _SC_MB_LEN_MAX
5863 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
5864#endif
5865#ifdef _SC_MEMLOCK
5866 {"SC_MEMLOCK", _SC_MEMLOCK},
5867#endif
5868#ifdef _SC_MEMLOCK_RANGE
5869 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
5870#endif
5871#ifdef _SC_MEMORY_PROTECTION
5872 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
5873#endif
5874#ifdef _SC_MESSAGE_PASSING
5875 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
5876#endif
Fred Draked86ed291999-12-15 15:34:33 +00005877#ifdef _SC_MMAP_FIXED_ALIGNMENT
5878 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
5879#endif
Fred Drakec9680921999-12-13 16:37:25 +00005880#ifdef _SC_MQ_OPEN_MAX
5881 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
5882#endif
5883#ifdef _SC_MQ_PRIO_MAX
5884 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
5885#endif
Fred Draked86ed291999-12-15 15:34:33 +00005886#ifdef _SC_NACLS_MAX
5887 {"SC_NACLS_MAX", _SC_NACLS_MAX},
5888#endif
Fred Drakec9680921999-12-13 16:37:25 +00005889#ifdef _SC_NGROUPS_MAX
5890 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
5891#endif
5892#ifdef _SC_NL_ARGMAX
5893 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
5894#endif
5895#ifdef _SC_NL_LANGMAX
5896 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
5897#endif
5898#ifdef _SC_NL_MSGMAX
5899 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
5900#endif
5901#ifdef _SC_NL_NMAX
5902 {"SC_NL_NMAX", _SC_NL_NMAX},
5903#endif
5904#ifdef _SC_NL_SETMAX
5905 {"SC_NL_SETMAX", _SC_NL_SETMAX},
5906#endif
5907#ifdef _SC_NL_TEXTMAX
5908 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
5909#endif
5910#ifdef _SC_NPROCESSORS_CONF
5911 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
5912#endif
5913#ifdef _SC_NPROCESSORS_ONLN
5914 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
5915#endif
Fred Draked86ed291999-12-15 15:34:33 +00005916#ifdef _SC_NPROC_CONF
5917 {"SC_NPROC_CONF", _SC_NPROC_CONF},
5918#endif
5919#ifdef _SC_NPROC_ONLN
5920 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
5921#endif
Fred Drakec9680921999-12-13 16:37:25 +00005922#ifdef _SC_NZERO
5923 {"SC_NZERO", _SC_NZERO},
5924#endif
5925#ifdef _SC_OPEN_MAX
5926 {"SC_OPEN_MAX", _SC_OPEN_MAX},
5927#endif
5928#ifdef _SC_PAGESIZE
5929 {"SC_PAGESIZE", _SC_PAGESIZE},
5930#endif
5931#ifdef _SC_PAGE_SIZE
5932 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
5933#endif
5934#ifdef _SC_PASS_MAX
5935 {"SC_PASS_MAX", _SC_PASS_MAX},
5936#endif
5937#ifdef _SC_PHYS_PAGES
5938 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
5939#endif
5940#ifdef _SC_PII
5941 {"SC_PII", _SC_PII},
5942#endif
5943#ifdef _SC_PII_INTERNET
5944 {"SC_PII_INTERNET", _SC_PII_INTERNET},
5945#endif
5946#ifdef _SC_PII_INTERNET_DGRAM
5947 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
5948#endif
5949#ifdef _SC_PII_INTERNET_STREAM
5950 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
5951#endif
5952#ifdef _SC_PII_OSI
5953 {"SC_PII_OSI", _SC_PII_OSI},
5954#endif
5955#ifdef _SC_PII_OSI_CLTS
5956 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
5957#endif
5958#ifdef _SC_PII_OSI_COTS
5959 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
5960#endif
5961#ifdef _SC_PII_OSI_M
5962 {"SC_PII_OSI_M", _SC_PII_OSI_M},
5963#endif
5964#ifdef _SC_PII_SOCKET
5965 {"SC_PII_SOCKET", _SC_PII_SOCKET},
5966#endif
5967#ifdef _SC_PII_XTI
5968 {"SC_PII_XTI", _SC_PII_XTI},
5969#endif
5970#ifdef _SC_POLL
5971 {"SC_POLL", _SC_POLL},
5972#endif
5973#ifdef _SC_PRIORITIZED_IO
5974 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
5975#endif
5976#ifdef _SC_PRIORITY_SCHEDULING
5977 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
5978#endif
5979#ifdef _SC_REALTIME_SIGNALS
5980 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
5981#endif
5982#ifdef _SC_RE_DUP_MAX
5983 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
5984#endif
5985#ifdef _SC_RTSIG_MAX
5986 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
5987#endif
5988#ifdef _SC_SAVED_IDS
5989 {"SC_SAVED_IDS", _SC_SAVED_IDS},
5990#endif
5991#ifdef _SC_SCHAR_MAX
5992 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
5993#endif
5994#ifdef _SC_SCHAR_MIN
5995 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
5996#endif
5997#ifdef _SC_SELECT
5998 {"SC_SELECT", _SC_SELECT},
5999#endif
6000#ifdef _SC_SEMAPHORES
6001 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6002#endif
6003#ifdef _SC_SEM_NSEMS_MAX
6004 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6005#endif
6006#ifdef _SC_SEM_VALUE_MAX
6007 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6008#endif
6009#ifdef _SC_SHARED_MEMORY_OBJECTS
6010 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6011#endif
6012#ifdef _SC_SHRT_MAX
6013 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6014#endif
6015#ifdef _SC_SHRT_MIN
6016 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6017#endif
6018#ifdef _SC_SIGQUEUE_MAX
6019 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6020#endif
6021#ifdef _SC_SIGRT_MAX
6022 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6023#endif
6024#ifdef _SC_SIGRT_MIN
6025 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6026#endif
Fred Draked86ed291999-12-15 15:34:33 +00006027#ifdef _SC_SOFTPOWER
6028 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6029#endif
Fred Drakec9680921999-12-13 16:37:25 +00006030#ifdef _SC_SPLIT_CACHE
6031 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6032#endif
6033#ifdef _SC_SSIZE_MAX
6034 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6035#endif
6036#ifdef _SC_STACK_PROT
6037 {"SC_STACK_PROT", _SC_STACK_PROT},
6038#endif
6039#ifdef _SC_STREAM_MAX
6040 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6041#endif
6042#ifdef _SC_SYNCHRONIZED_IO
6043 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6044#endif
6045#ifdef _SC_THREADS
6046 {"SC_THREADS", _SC_THREADS},
6047#endif
6048#ifdef _SC_THREAD_ATTR_STACKADDR
6049 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6050#endif
6051#ifdef _SC_THREAD_ATTR_STACKSIZE
6052 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6053#endif
6054#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6055 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6056#endif
6057#ifdef _SC_THREAD_KEYS_MAX
6058 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6059#endif
6060#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6061 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6062#endif
6063#ifdef _SC_THREAD_PRIO_INHERIT
6064 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6065#endif
6066#ifdef _SC_THREAD_PRIO_PROTECT
6067 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6068#endif
6069#ifdef _SC_THREAD_PROCESS_SHARED
6070 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6071#endif
6072#ifdef _SC_THREAD_SAFE_FUNCTIONS
6073 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6074#endif
6075#ifdef _SC_THREAD_STACK_MIN
6076 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6077#endif
6078#ifdef _SC_THREAD_THREADS_MAX
6079 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6080#endif
6081#ifdef _SC_TIMERS
6082 {"SC_TIMERS", _SC_TIMERS},
6083#endif
6084#ifdef _SC_TIMER_MAX
6085 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6086#endif
6087#ifdef _SC_TTY_NAME_MAX
6088 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6089#endif
6090#ifdef _SC_TZNAME_MAX
6091 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6092#endif
6093#ifdef _SC_T_IOV_MAX
6094 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6095#endif
6096#ifdef _SC_UCHAR_MAX
6097 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6098#endif
6099#ifdef _SC_UINT_MAX
6100 {"SC_UINT_MAX", _SC_UINT_MAX},
6101#endif
6102#ifdef _SC_UIO_MAXIOV
6103 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6104#endif
6105#ifdef _SC_ULONG_MAX
6106 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6107#endif
6108#ifdef _SC_USHRT_MAX
6109 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6110#endif
6111#ifdef _SC_VERSION
6112 {"SC_VERSION", _SC_VERSION},
6113#endif
6114#ifdef _SC_WORD_BIT
6115 {"SC_WORD_BIT", _SC_WORD_BIT},
6116#endif
6117#ifdef _SC_XBS5_ILP32_OFF32
6118 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6119#endif
6120#ifdef _SC_XBS5_ILP32_OFFBIG
6121 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6122#endif
6123#ifdef _SC_XBS5_LP64_OFF64
6124 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6125#endif
6126#ifdef _SC_XBS5_LPBIG_OFFBIG
6127 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6128#endif
6129#ifdef _SC_XOPEN_CRYPT
6130 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6131#endif
6132#ifdef _SC_XOPEN_ENH_I18N
6133 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6134#endif
6135#ifdef _SC_XOPEN_LEGACY
6136 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6137#endif
6138#ifdef _SC_XOPEN_REALTIME
6139 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6140#endif
6141#ifdef _SC_XOPEN_REALTIME_THREADS
6142 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6143#endif
6144#ifdef _SC_XOPEN_SHM
6145 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6146#endif
6147#ifdef _SC_XOPEN_UNIX
6148 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6149#endif
6150#ifdef _SC_XOPEN_VERSION
6151 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6152#endif
6153#ifdef _SC_XOPEN_XCU_VERSION
6154 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6155#endif
6156#ifdef _SC_XOPEN_XPG2
6157 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6158#endif
6159#ifdef _SC_XOPEN_XPG3
6160 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6161#endif
6162#ifdef _SC_XOPEN_XPG4
6163 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6164#endif
6165};
6166
6167static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006168conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006169{
6170 return conv_confname(arg, valuep, posix_constants_sysconf,
6171 sizeof(posix_constants_sysconf)
6172 / sizeof(struct constdef));
6173}
6174
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006176"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006177Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006178
6179static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006180posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006181{
6182 PyObject *result = NULL;
6183 int name;
6184
6185 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6186 int value;
6187
6188 errno = 0;
6189 value = sysconf(name);
6190 if (value == -1 && errno != 0)
6191 posix_error();
6192 else
6193 result = PyInt_FromLong(value);
6194 }
6195 return result;
6196}
6197#endif
6198
6199
Fred Drakebec628d1999-12-15 18:31:10 +00006200/* This code is used to ensure that the tables of configuration value names
6201 * are in sorted order as required by conv_confname(), and also to build the
6202 * the exported dictionaries that are used to publish information about the
6203 * names available on the host platform.
6204 *
6205 * Sorting the table at runtime ensures that the table is properly ordered
6206 * when used, even for platforms we're not able to test on. It also makes
6207 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006208 */
Fred Drakebec628d1999-12-15 18:31:10 +00006209
6210static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006211cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006212{
6213 const struct constdef *c1 =
6214 (const struct constdef *) v1;
6215 const struct constdef *c2 =
6216 (const struct constdef *) v2;
6217
6218 return strcmp(c1->name, c2->name);
6219}
6220
6221static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006222setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006223 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006224{
Fred Drakebec628d1999-12-15 18:31:10 +00006225 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006226 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006227
6228 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6229 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006230 if (d == NULL)
6231 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006232
Barry Warsaw3155db32000-04-13 15:20:40 +00006233 for (i=0; i < tablesize; ++i) {
6234 PyObject *o = PyInt_FromLong(table[i].value);
6235 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6236 Py_XDECREF(o);
6237 Py_DECREF(d);
6238 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006239 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006240 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006241 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006242 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006243}
6244
Fred Drakebec628d1999-12-15 18:31:10 +00006245/* Return -1 on failure, 0 on success. */
6246static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006247setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006248{
6249#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006250 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006251 sizeof(posix_constants_pathconf)
6252 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006253 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006254 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006255#endif
6256#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006257 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006258 sizeof(posix_constants_confstr)
6259 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006260 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006261 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006262#endif
6263#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006264 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006265 sizeof(posix_constants_sysconf)
6266 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006267 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006268 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006269#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006270 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006271}
Fred Draked86ed291999-12-15 15:34:33 +00006272
6273
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006274PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006275"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006276Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006277in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006278
6279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006280posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006281{
6282 if (!PyArg_ParseTuple(args, ":abort"))
6283 return NULL;
6284 abort();
6285 /*NOTREACHED*/
6286 Py_FatalError("abort() called from Python code didn't abort!");
6287 return NULL;
6288}
Fred Drakebec628d1999-12-15 18:31:10 +00006289
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006290#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006291PyDoc_STRVAR(win32_startfile__doc__,
6292"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006293\n\
6294This acts like double-clicking the file in Explorer, or giving the file\n\
6295name as an argument to the DOS \"start\" command: the file is opened\n\
6296with whatever application (if any) its extension is associated.\n\
6297\n\
6298startfile returns as soon as the associated application is launched.\n\
6299There is no option to wait for the application to close, and no way\n\
6300to retrieve the application's exit status.\n\
6301\n\
6302The filepath is relative to the current directory. If you want to use\n\
6303an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006304the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006305
6306static PyObject *
6307win32_startfile(PyObject *self, PyObject *args)
6308{
6309 char *filepath;
6310 HINSTANCE rc;
6311 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6312 return NULL;
6313 Py_BEGIN_ALLOW_THREADS
6314 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6315 Py_END_ALLOW_THREADS
6316 if (rc <= (HINSTANCE)32)
6317 return win32_error("startfile", filepath);
6318 Py_INCREF(Py_None);
6319 return Py_None;
6320}
6321#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006322
6323static PyMethodDef posix_methods[] = {
6324 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6325#ifdef HAVE_TTYNAME
6326 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6327#endif
6328 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6329 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006330#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006331 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006332#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006333#ifdef HAVE_LCHOWN
6334 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6335#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006336#ifdef HAVE_CHROOT
6337 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6338#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006339#ifdef HAVE_CTERMID
6340 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6341#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006342#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006343 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006344#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006345#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006346 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006347#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006348 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6349 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6350 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006351#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006352 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006353#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006354#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006355 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006356#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006357 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6358 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6359 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006360#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006361 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006362#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006363#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006364 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006365#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006366 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006367#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006368 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006369#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006370 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6371 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6372 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006373#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006374 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006375#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006376 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006377#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006378 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6379 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006380#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006381#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006382 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6383 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006384#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006385#ifdef HAVE_FORK1
6386 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6387#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006388#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006389 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006390#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006391#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006392 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006393#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006394#ifdef HAVE_FORKPTY
6395 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6396#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006397#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006398 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006399#endif /* HAVE_GETEGID */
6400#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006401 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006402#endif /* HAVE_GETEUID */
6403#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006404 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006405#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006406#ifdef HAVE_GETGROUPS
6407 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6408#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006409 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006410#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006411 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006412#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006413#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006414 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006415#endif /* HAVE_GETPPID */
6416#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006417 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006418#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006419#ifdef HAVE_GETLOGIN
6420 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6421#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006422#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006423 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006424#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006425#ifdef HAVE_KILLPG
6426 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6427#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006428#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006429 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006430#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006431#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006432 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006433#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006434 {"popen2", win32_popen2, METH_VARARGS},
6435 {"popen3", win32_popen3, METH_VARARGS},
6436 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006437 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006438#else
6439#if defined(PYOS_OS2) && defined(PYCC_GCC)
6440 {"popen2", os2emx_popen2, METH_VARARGS},
6441 {"popen3", os2emx_popen3, METH_VARARGS},
6442 {"popen4", os2emx_popen4, METH_VARARGS},
6443#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006444#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006445#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006446#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006447 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006448#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006449#ifdef HAVE_SETEUID
6450 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6451#endif /* HAVE_SETEUID */
6452#ifdef HAVE_SETEGID
6453 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6454#endif /* HAVE_SETEGID */
6455#ifdef HAVE_SETREUID
6456 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6457#endif /* HAVE_SETREUID */
6458#ifdef HAVE_SETREGID
6459 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6460#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006461#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006462 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006463#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006464#ifdef HAVE_SETGROUPS
6465 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6466#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006467#ifdef HAVE_GETPGID
6468 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6469#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006470#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006471 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006472#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006473#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006474 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006475#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006476#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006477 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006478#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006479#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006480 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006481#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006482#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006483 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006484#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006485#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006486 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006487#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006488#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006489 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006490#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006491 {"open", posix_open, METH_VARARGS, posix_open__doc__},
6492 {"close", posix_close, METH_VARARGS, posix_close__doc__},
6493 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
6494 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
6495 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
6496 {"read", posix_read, METH_VARARGS, posix_read__doc__},
6497 {"write", posix_write, METH_VARARGS, posix_write__doc__},
6498 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
6499 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00006500 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006501#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006502 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006503#endif
6504#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006505 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006506#endif
Neal Norwitz11690112002-07-30 01:08:28 +00006507#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006508 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
6509#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006510#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006511 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006512#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006513#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006514 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006515#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00006516#ifdef HAVE_UNSETENV
6517 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
6518#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00006519#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006520 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00006521#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00006522#ifdef HAVE_FCHDIR
6523 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
6524#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00006525#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006526 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006527#endif
6528#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00006529 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00006530#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00006531#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00006532#ifdef WCOREDUMP
6533 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
6534#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006535#ifdef WIFCONTINUED
6536 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
6537#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00006538#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006539 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006540#endif /* WIFSTOPPED */
6541#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006542 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006543#endif /* WIFSIGNALED */
6544#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006545 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006546#endif /* WIFEXITED */
6547#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006548 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006549#endif /* WEXITSTATUS */
6550#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006551 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006552#endif /* WTERMSIG */
6553#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006554 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00006555#endif /* WSTOPSIG */
6556#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006557#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006558 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006559#endif
6560#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006561 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00006562#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00006563#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006564 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
6565#endif
6566#ifdef HAVE_TEMPNAM
6567 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
6568#endif
6569#ifdef HAVE_TMPNAM
6570 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
6571#endif
Fred Drakec9680921999-12-13 16:37:25 +00006572#ifdef HAVE_CONFSTR
6573 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
6574#endif
6575#ifdef HAVE_SYSCONF
6576 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
6577#endif
6578#ifdef HAVE_FPATHCONF
6579 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
6580#endif
6581#ifdef HAVE_PATHCONF
6582 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
6583#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006584 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006585#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00006586 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
6587#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006588 {NULL, NULL} /* Sentinel */
6589};
6590
6591
Barry Warsaw4a342091996-12-19 23:50:02 +00006592static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006593ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00006594{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006595 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00006596}
6597
Guido van Rossumd48f2521997-12-05 22:19:34 +00006598#if defined(PYOS_OS2)
6599/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006600static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006601{
6602 APIRET rc;
6603 ULONG values[QSV_MAX+1];
6604 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00006605 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00006606
6607 Py_BEGIN_ALLOW_THREADS
6608 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
6609 Py_END_ALLOW_THREADS
6610
6611 if (rc != NO_ERROR) {
6612 os2_error(rc);
6613 return -1;
6614 }
6615
Fred Drake4d1e64b2002-04-15 19:40:07 +00006616 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
6617 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
6618 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
6619 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
6620 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
6621 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
6622 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006623
6624 switch (values[QSV_VERSION_MINOR]) {
6625 case 0: ver = "2.00"; break;
6626 case 10: ver = "2.10"; break;
6627 case 11: ver = "2.11"; break;
6628 case 30: ver = "3.00"; break;
6629 case 40: ver = "4.00"; break;
6630 case 50: ver = "5.00"; break;
6631 default:
Tim Peters885d4572001-11-28 20:27:42 +00006632 PyOS_snprintf(tmp, sizeof(tmp),
6633 "%d-%d", values[QSV_VERSION_MAJOR],
6634 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006635 ver = &tmp[0];
6636 }
6637
6638 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00006639 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006640 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006641
6642 /* Add Indicator of Which Drive was Used to Boot the System */
6643 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
6644 tmp[1] = ':';
6645 tmp[2] = '\0';
6646
Fred Drake4d1e64b2002-04-15 19:40:07 +00006647 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00006648}
6649#endif
6650
Barry Warsaw4a342091996-12-19 23:50:02 +00006651static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006652all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00006653{
Guido van Rossum94f6f721999-01-06 18:42:14 +00006654#ifdef F_OK
6655 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006656#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006657#ifdef R_OK
6658 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006659#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006660#ifdef W_OK
6661 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006662#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006663#ifdef X_OK
6664 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006665#endif
Fred Drakec9680921999-12-13 16:37:25 +00006666#ifdef NGROUPS_MAX
6667 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
6668#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006669#ifdef TMP_MAX
6670 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
6671#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006672#ifdef WCONTINUED
6673 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
6674#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006675#ifdef WNOHANG
6676 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00006677#endif
Fred Drake106c1a02002-04-23 15:58:02 +00006678#ifdef WUNTRACED
6679 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
6680#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006681#ifdef O_RDONLY
6682 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
6683#endif
6684#ifdef O_WRONLY
6685 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
6686#endif
6687#ifdef O_RDWR
6688 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
6689#endif
6690#ifdef O_NDELAY
6691 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
6692#endif
6693#ifdef O_NONBLOCK
6694 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
6695#endif
6696#ifdef O_APPEND
6697 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
6698#endif
6699#ifdef O_DSYNC
6700 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
6701#endif
6702#ifdef O_RSYNC
6703 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
6704#endif
6705#ifdef O_SYNC
6706 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
6707#endif
6708#ifdef O_NOCTTY
6709 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
6710#endif
6711#ifdef O_CREAT
6712 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
6713#endif
6714#ifdef O_EXCL
6715 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
6716#endif
6717#ifdef O_TRUNC
6718 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
6719#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00006720#ifdef O_BINARY
6721 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
6722#endif
6723#ifdef O_TEXT
6724 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
6725#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006726#ifdef O_LARGEFILE
6727 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
6728#endif
6729
Tim Peters5aa91602002-01-30 05:46:57 +00006730/* MS Windows */
6731#ifdef O_NOINHERIT
6732 /* Don't inherit in child processes. */
6733 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
6734#endif
6735#ifdef _O_SHORT_LIVED
6736 /* Optimize for short life (keep in memory). */
6737 /* MS forgot to define this one with a non-underscore form too. */
6738 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
6739#endif
6740#ifdef O_TEMPORARY
6741 /* Automatically delete when last handle is closed. */
6742 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
6743#endif
6744#ifdef O_RANDOM
6745 /* Optimize for random access. */
6746 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
6747#endif
6748#ifdef O_SEQUENTIAL
6749 /* Optimize for sequential access. */
6750 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
6751#endif
6752
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00006753/* GNU extensions. */
6754#ifdef O_DIRECT
6755 /* Direct disk access. */
6756 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
6757#endif
6758#ifdef O_DIRECTORY
6759 /* Must be a directory. */
6760 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
6761#endif
6762#ifdef O_NOFOLLOW
6763 /* Do not follow links. */
6764 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
6765#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00006766
Guido van Rossum246bc171999-02-01 23:54:31 +00006767#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006768#if defined(PYOS_OS2) && defined(PYCC_GCC)
6769 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
6770 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
6771 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
6772 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
6773 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
6774 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
6775 if (ins(d, "P_PM", (long)P_PM)) return -1;
6776 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
6777 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
6778 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
6779 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
6780 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
6781 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
6782 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
6783 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
6784 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
6785 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
6786 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
6787 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
6788 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
6789#else
Guido van Rossum7d385291999-02-16 19:38:04 +00006790 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
6791 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
6792 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
6793 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
6794 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00006795#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006796#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00006797
Guido van Rossumd48f2521997-12-05 22:19:34 +00006798#if defined(PYOS_OS2)
6799 if (insertvalues(d)) return -1;
6800#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00006801 return 0;
6802}
6803
6804
Tim Peters5aa91602002-01-30 05:46:57 +00006805#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006806#define INITFUNC initnt
6807#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006808
6809#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006810#define INITFUNC initos2
6811#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00006812
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006813#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006814#define INITFUNC initposix
6815#define MODNAME "posix"
6816#endif
6817
Mark Hammondfe51c6d2002-08-02 02:27:13 +00006818PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00006819INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00006820{
Fred Drake4d1e64b2002-04-15 19:40:07 +00006821 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00006822
Fred Drake4d1e64b2002-04-15 19:40:07 +00006823 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006824 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006825 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00006826
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006827 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006828 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00006829 Py_XINCREF(v);
6830 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00006831 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00006832 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00006833
Fred Drake4d1e64b2002-04-15 19:40:07 +00006834 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00006835 return;
6836
Fred Drake4d1e64b2002-04-15 19:40:07 +00006837 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00006838 return;
6839
Fred Drake4d1e64b2002-04-15 19:40:07 +00006840 Py_INCREF(PyExc_OSError);
6841 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00006842
Guido van Rossumb3d39562000-01-31 18:41:26 +00006843#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00006844 if (posix_putenv_garbage == NULL)
6845 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00006846#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006847
Guido van Rossum14648392001-12-08 18:02:58 +00006848 stat_result_desc.name = MODNAME ".stat_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006849 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006850 Py_INCREF((PyObject*) &StatResultType);
6851 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006852
Guido van Rossum14648392001-12-08 18:02:58 +00006853 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006854 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00006855 Py_INCREF((PyObject*) &StatVFSResultType);
6856 PyModule_AddObject(m, "statvfs_result",
6857 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00006858}