blob: 9dc1d05d08ed7ed580f7757f8dae36603ef9a5c2 [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
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000280#if defined(MAJOR_IN_MKDEV)
281#include <sys/mkdev.h>
282#else
283#if defined(MAJOR_IN_SYSMACROS)
284#include <sys/sysmacros.h>
285#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000286#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
287#include <sys/mkdev.h>
288#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000289#endif
Fred Drake699f3522000-06-29 21:12:41 +0000290
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000292#ifdef WITH_NEXT_FRAMEWORK
293/* On Darwin/MacOSX a shared library or framework has no access to
294** environ directly, we must obtain it with _NSGetEnviron().
295*/
296#include <crt_externs.h>
297static char **environ;
298#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000299extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000300#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301
Barry Warsaw53699e91996-12-10 23:23:01 +0000302static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000303convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304{
Barry Warsaw53699e91996-12-10 23:23:01 +0000305 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000307 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308 if (d == NULL)
309 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000310#ifdef WITH_NEXT_FRAMEWORK
311 if (environ == NULL)
312 environ = *_NSGetEnviron();
313#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000314 if (environ == NULL)
315 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000316 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000318 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000319 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000320 char *p = strchr(*e, '=');
321 if (p == NULL)
322 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000323 k = PyString_FromStringAndSize(*e, (int)(p-*e));
324 if (k == NULL) {
325 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000326 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000327 }
328 v = PyString_FromString(p+1);
329 if (v == NULL) {
330 PyErr_Clear();
331 Py_DECREF(k);
332 continue;
333 }
334 if (PyDict_GetItem(d, k) == NULL) {
335 if (PyDict_SetItem(d, k, v) != 0)
336 PyErr_Clear();
337 }
338 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000339 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000340 }
Guido van Rossumd48f2521997-12-05 22:19:34 +0000341#if defined(PYOS_OS2)
342 {
343 APIRET rc;
344 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
345
346 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000347 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000348 PyObject *v = PyString_FromString(buffer);
349 PyDict_SetItemString(d, "BEGINLIBPATH", v);
350 Py_DECREF(v);
351 }
352 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
353 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
354 PyObject *v = PyString_FromString(buffer);
355 PyDict_SetItemString(d, "ENDLIBPATH", v);
356 Py_DECREF(v);
357 }
358 }
359#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000360 return d;
361}
362
363
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000364/* Set a POSIX-specific error from errno, and return NULL */
365
Barry Warsawd58d7641998-07-23 16:14:40 +0000366static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000367posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000368{
Barry Warsawca74da41999-02-09 19:31:45 +0000369 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000370}
Barry Warsawd58d7641998-07-23 16:14:40 +0000371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000372posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000373{
Barry Warsawca74da41999-02-09 19:31:45 +0000374 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000375}
376
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000377#ifdef Py_WIN_WIDE_FILENAMES
378static PyObject *
379posix_error_with_unicode_filename(Py_UNICODE* name)
380{
381 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
382}
383#endif /* Py_WIN_WIDE_FILENAMES */
384
385
Mark Hammondef8b6542001-05-13 08:04:26 +0000386static PyObject *
387posix_error_with_allocated_filename(char* name)
388{
389 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
390 PyMem_Free(name);
391 return rc;
392}
393
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000394#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000395static PyObject *
396win32_error(char* function, char* filename)
397{
Mark Hammond33a6da92000-08-15 00:46:38 +0000398 /* XXX We should pass the function name along in the future.
399 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000400 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000401 Windows error object, which is non-trivial.
402 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000403 errno = GetLastError();
404 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000405 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000406 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000407 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000408}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000409
410#ifdef Py_WIN_WIDE_FILENAMES
411static PyObject *
412win32_error_unicode(char* function, Py_UNICODE* filename)
413{
414 /* XXX - see win32_error for comments on 'function' */
415 errno = GetLastError();
416 if (filename)
417 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
418 else
419 return PyErr_SetFromWindowsErr(errno);
420}
421
422static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
423{
424 /* XXX Perhaps we should make this API an alias of
425 PyObject_Unicode() instead ?! */
426 if (PyUnicode_CheckExact(obj)) {
427 Py_INCREF(obj);
428 return obj;
429 }
430 if (PyUnicode_Check(obj)) {
431 /* For a Unicode subtype that's not a Unicode object,
432 return a true Unicode object with the same data. */
433 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
434 PyUnicode_GET_SIZE(obj));
435 }
436 return PyUnicode_FromEncodedObject(obj,
437 Py_FileSystemDefaultEncoding,
438 "strict");
439}
440
441#endif /* Py_WIN_WIDE_FILENAMES */
442
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000443#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000444
Guido van Rossumd48f2521997-12-05 22:19:34 +0000445#if defined(PYOS_OS2)
446/**********************************************************************
447 * Helper Function to Trim and Format OS/2 Messages
448 **********************************************************************/
449 static void
450os2_formatmsg(char *msgbuf, int msglen, char *reason)
451{
452 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
453
454 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
455 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
456
457 while (lastc > msgbuf && isspace(*lastc))
458 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
459 }
460
461 /* Add Optional Reason Text */
462 if (reason) {
463 strcat(msgbuf, " : ");
464 strcat(msgbuf, reason);
465 }
466}
467
468/**********************************************************************
469 * Decode an OS/2 Operating System Error Code
470 *
471 * A convenience function to lookup an OS/2 error code and return a
472 * text message we can use to raise a Python exception.
473 *
474 * Notes:
475 * The messages for errors returned from the OS/2 kernel reside in
476 * the file OSO001.MSG in the \OS2 directory hierarchy.
477 *
478 **********************************************************************/
479 static char *
480os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
481{
482 APIRET rc;
483 ULONG msglen;
484
485 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
486 Py_BEGIN_ALLOW_THREADS
487 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
488 errorcode, "oso001.msg", &msglen);
489 Py_END_ALLOW_THREADS
490
491 if (rc == NO_ERROR)
492 os2_formatmsg(msgbuf, msglen, reason);
493 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000494 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000495 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000496
497 return msgbuf;
498}
499
500/* Set an OS/2-specific error and return NULL. OS/2 kernel
501 errors are not in a global variable e.g. 'errno' nor are
502 they congruent with posix error numbers. */
503
504static PyObject * os2_error(int code)
505{
506 char text[1024];
507 PyObject *v;
508
509 os2_strerror(text, sizeof(text), code, "");
510
511 v = Py_BuildValue("(is)", code, text);
512 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000513 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000514 Py_DECREF(v);
515 }
516 return NULL; /* Signal to Python that an Exception is Pending */
517}
518
519#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000520
521/* POSIX generic methods */
522
Barry Warsaw53699e91996-12-10 23:23:01 +0000523static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000524posix_fildes(PyObject *fdobj, int (*func)(int))
525{
526 int fd;
527 int res;
528 fd = PyObject_AsFileDescriptor(fdobj);
529 if (fd < 0)
530 return NULL;
531 Py_BEGIN_ALLOW_THREADS
532 res = (*func)(fd);
533 Py_END_ALLOW_THREADS
534 if (res < 0)
535 return posix_error();
536 Py_INCREF(Py_None);
537 return Py_None;
538}
Guido van Rossum21142a01999-01-08 21:05:37 +0000539
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000540#ifdef Py_WIN_WIDE_FILENAMES
541static int
542unicode_file_names(void)
543{
544 static int canusewide = -1;
545 if (canusewide == -1) {
546 /* As per doc for ::GetVersion(), this is the correct test for
547 the Windows NT family. */
548 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
549 }
550 return canusewide;
551}
552#endif
553
Guido van Rossum21142a01999-01-08 21:05:37 +0000554static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000555posix_1str(PyObject *args, char *format, int (*func)(const char*),
556 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000557{
Mark Hammondef8b6542001-05-13 08:04:26 +0000558 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000559 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000560#ifdef Py_WIN_WIDE_FILENAMES
561 if (unicode_file_names()) {
562 PyUnicodeObject *po;
563 if (PyArg_ParseTuple(args, wformat, &po)) {
564 Py_BEGIN_ALLOW_THREADS
565 /* PyUnicode_AS_UNICODE OK without thread
566 lock as it is a simple dereference. */
567 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
568 Py_END_ALLOW_THREADS
569 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000570 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000571 Py_INCREF(Py_None);
572 return Py_None;
573 }
574 /* Drop the argument parsing error as narrow
575 strings are also valid. */
576 PyErr_Clear();
577 }
578#else
579 /* Platforms that don't support Unicode filenames
580 shouldn't be passing these extra params */
581 assert(wformat==NULL && wfunc == NULL);
582#endif
583
Tim Peters5aa91602002-01-30 05:46:57 +0000584 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000585 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000586 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000587 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000588 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000589 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000590 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000591 return posix_error_with_allocated_filename(path1);
592 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000593 Py_INCREF(Py_None);
594 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000595}
596
Barry Warsaw53699e91996-12-10 23:23:01 +0000597static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000598posix_2str(PyObject *args,
599 char *format,
600 int (*func)(const char *, const char *),
601 char *wformat,
602 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603{
Mark Hammondef8b6542001-05-13 08:04:26 +0000604 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000605 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000606#ifdef Py_WIN_WIDE_FILENAMES
607 if (unicode_file_names()) {
608 PyObject *po1;
609 PyObject *po2;
610 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
611 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
612 PyObject *wpath1;
613 PyObject *wpath2;
614 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
615 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
616 if (!wpath1 || !wpath2) {
617 Py_XDECREF(wpath1);
618 Py_XDECREF(wpath2);
619 return NULL;
620 }
621 Py_BEGIN_ALLOW_THREADS
622 /* PyUnicode_AS_UNICODE OK without thread
623 lock as it is a simple dereference. */
624 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
625 PyUnicode_AS_UNICODE(wpath2));
626 Py_END_ALLOW_THREADS
627 Py_XDECREF(wpath1);
628 Py_XDECREF(wpath2);
629 if (res != 0)
630 return posix_error();
631 Py_INCREF(Py_None);
632 return Py_None;
633 }
634 /* Else flow through as neither is Unicode. */
635 }
636 /* Drop the argument parsing error as narrow
637 strings are also valid. */
638 PyErr_Clear();
639 }
640#else
641 /* Platforms that don't support Unicode filenames
642 shouldn't be passing these extra params */
643 assert(wformat==NULL && wfunc == NULL);
644#endif
645
Mark Hammondef8b6542001-05-13 08:04:26 +0000646 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000647 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000648 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000649 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000650 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000651 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000652 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000653 PyMem_Free(path1);
654 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000655 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000656 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000657 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000658 Py_INCREF(Py_None);
659 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000660}
661
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000662PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000663"stat_result: Result from stat or lstat.\n\n\
664This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000665 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000666or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
667\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000668Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000669they are available as attributes only.\n\
670\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000671See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000672
673static PyStructSequence_Field stat_result_fields[] = {
674 {"st_mode", "protection bits"},
675 {"st_ino", "inode"},
676 {"st_dev", "device"},
677 {"st_nlink", "number of hard links"},
678 {"st_uid", "user ID of owner"},
679 {"st_gid", "group ID of owner"},
680 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000681 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
682 {NULL, "integer time of last access"},
683 {NULL, "integer time of last modification"},
684 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000685 {"st_atime", "time of last access"},
686 {"st_mtime", "time of last modification"},
687 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000688#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000689 {"st_blksize", "blocksize for filesystem I/O"},
690#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000691#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000692 {"st_blocks", "number of blocks allocated"},
693#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000694#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000695 {"st_rdev", "device type (if inode device)"},
696#endif
697 {0}
698};
699
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000700#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000701#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000702#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000703#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000704#endif
705
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000706#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000707#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
708#else
709#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
710#endif
711
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000712#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000713#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
714#else
715#define ST_RDEV_IDX ST_BLOCKS_IDX
716#endif
717
718static PyStructSequence_Desc stat_result_desc = {
719 "stat_result", /* name */
720 stat_result__doc__, /* doc */
721 stat_result_fields,
722 10
723};
724
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000725PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000726"statvfs_result: Result from statvfs or fstatvfs.\n\n\
727This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000728 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000729or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000730\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000731See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000732
733static PyStructSequence_Field statvfs_result_fields[] = {
734 {"f_bsize", },
735 {"f_frsize", },
736 {"f_blocks", },
737 {"f_bfree", },
738 {"f_bavail", },
739 {"f_files", },
740 {"f_ffree", },
741 {"f_favail", },
742 {"f_flag", },
743 {"f_namemax",},
744 {0}
745};
746
747static PyStructSequence_Desc statvfs_result_desc = {
748 "statvfs_result", /* name */
749 statvfs_result__doc__, /* doc */
750 statvfs_result_fields,
751 10
752};
753
754static PyTypeObject StatResultType;
755static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000756static newfunc structseq_new;
757
758static PyObject *
759statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
760{
761 PyStructSequence *result;
762 int i;
763
764 result = (PyStructSequence*)structseq_new(type, args, kwds);
765 if (!result)
766 return NULL;
767 /* If we have been initialized from a tuple,
768 st_?time might be set to None. Initialize it
769 from the int slots. */
770 for (i = 7; i <= 9; i++) {
771 if (result->ob_item[i+3] == Py_None) {
772 Py_DECREF(Py_None);
773 Py_INCREF(result->ob_item[i]);
774 result->ob_item[i+3] = result->ob_item[i];
775 }
776 }
777 return (PyObject*)result;
778}
779
780
781
782/* If true, st_?time is float. */
783static int _stat_float_times = 0;
784
785PyDoc_STRVAR(stat_float_times__doc__,
786"stat_float_times([newval]) -> oldval\n\n\
787Determine whether os.[lf]stat represents time stamps as float objects.\n\
788If newval is True, future calls to stat() return floats, if it is False,\n\
789future calls return ints. \n\
790If newval is omitted, return the current setting.\n");
791
792static PyObject*
793stat_float_times(PyObject* self, PyObject *args)
794{
795 int newval = -1;
796 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
797 return NULL;
798 if (newval == -1)
799 /* Return old value */
800 return PyBool_FromLong(_stat_float_times);
801 _stat_float_times = newval;
802 Py_INCREF(Py_None);
803 return Py_None;
804}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000805
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000806static void
807fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
808{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000809 PyObject *fval,*ival;
810#if SIZEOF_TIME_T > SIZEOF_LONG
811 ival = PyLong_FromLongLong((LONG_LONG)sec);
812#else
813 ival = PyInt_FromLong((long)sec);
814#endif
815 if (_stat_float_times) {
816 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
817 } else {
818 fval = ival;
819 Py_INCREF(fval);
820 }
821 PyStructSequence_SET_ITEM(v, index, ival);
822 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000823}
824
Tim Peters5aa91602002-01-30 05:46:57 +0000825/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000826 (used by posix_stat() and posix_fstat()) */
827static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000828_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000829{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000830 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000831 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000832 if (v == NULL)
833 return NULL;
834
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000835 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000836#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000837 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000838 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000839#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000840 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000841#endif
842#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000843 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000844 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000845#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000846 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000847#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000848 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
849 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
850 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000851#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000852 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000853 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000854#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000855 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000856#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000857
858#ifdef HAVE_STAT_TV_NSEC
859 ansec = st.st_atim.tv_nsec;
860 mnsec = st.st_mtim.tv_nsec;
861 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000862#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000863 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000864#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000865 fill_time(v, 7, st.st_atime, ansec);
866 fill_time(v, 8, st.st_mtime, mnsec);
867 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000868
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000869#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000870 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000871 PyInt_FromLong((long)st.st_blksize));
872#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000873#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000874 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000875 PyInt_FromLong((long)st.st_blocks));
876#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000877#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000878 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
879 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000880#endif
881
882 if (PyErr_Occurred()) {
883 Py_DECREF(v);
884 return NULL;
885 }
886
887 return v;
888}
889
Barry Warsaw53699e91996-12-10 23:23:01 +0000890static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000891posix_do_stat(PyObject *self, PyObject *args,
892 char *format,
893 int (*statfunc)(const char *, STRUCT_STAT *),
894 char *wformat,
895 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000896{
Fred Drake699f3522000-06-29 21:12:41 +0000897 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000898 char *path = NULL; /* pass this to stat; do not free() it */
899 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000900 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000901
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000902#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000903 int pathlen;
904 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000905#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000906
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000907
908#ifdef Py_WIN_WIDE_FILENAMES
909 /* If on wide-character-capable OS see if argument
910 is Unicode and if so use wide API. */
911 if (unicode_file_names()) {
912 PyUnicodeObject *po;
913 if (PyArg_ParseTuple(args, wformat, &po)) {
914 Py_UNICODE wpath[MAX_PATH+1];
915 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
916 /* the library call can blow up if the file name is too long! */
917 if (pathlen > MAX_PATH) {
918 errno = ENAMETOOLONG;
919 return posix_error();
920 }
921 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
922 /* Remove trailing slash or backslash, unless it's the current
923 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
924 */
925 if (pathlen > 0 &&
926 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
927 /* It does end with a slash -- exempt the root drive cases. */
928 /* XXX UNC root drives should also be exempted? */
929 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
930 /* leave it alone */;
931 else {
932 /* nuke the trailing backslash */
933 wpath[pathlen-1] = L'\0';
934 }
935 }
936 Py_BEGIN_ALLOW_THREADS
937 /* PyUnicode_AS_UNICODE result OK without
938 thread lock as it is a simple dereference. */
939 res = wstatfunc(wpath, &st);
940 Py_END_ALLOW_THREADS
941 if (res != 0)
942 return posix_error_with_unicode_filename(wpath);
943 return _pystat_fromstructstat(st);
944 }
945 /* Drop the argument parsing error as narrow strings
946 are also valid. */
947 PyErr_Clear();
948 }
949#endif
950
Tim Peters5aa91602002-01-30 05:46:57 +0000951 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000952 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000953 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +0000954 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000955
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000956#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +0000957 pathlen = strlen(path);
958 /* the library call can blow up if the file name is too long! */
959 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +0000960 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +0000961 errno = ENAMETOOLONG;
962 return posix_error();
963 }
964
Tim Peters500bd032001-12-19 19:05:01 +0000965 /* Remove trailing slash or backslash, unless it's the current
966 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
967 */
968 if (pathlen > 0 &&
969 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
970 /* It does end with a slash -- exempt the root drive cases. */
971 /* XXX UNC root drives should also be exempted? */
972 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
973 /* leave it alone */;
974 else {
975 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000976 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +0000977 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +0000978 path = pathcopy;
979 }
980 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000981#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000982
Barry Warsaw53699e91996-12-10 23:23:01 +0000983 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000984 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +0000985 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000986 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +0000987 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000988
Tim Peters500bd032001-12-19 19:05:01 +0000989 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +0000990 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000991}
992
993
994/* POSIX methods */
995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000996PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +0000997"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +0000998Use the real uid/gid to test for access to a path. Note that most\n\
999operations will use the effective uid/gid, therefore this routine can\n\
1000be used in a suid/sgid environment to test if the invoking user has the\n\
1001specified access to the path. The mode argument can be F_OK to test\n\
1002existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001003
1004static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001005posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001006{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001007 char *path;
1008 int mode;
1009 int res;
1010
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001011 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001012 return NULL;
1013 Py_BEGIN_ALLOW_THREADS
1014 res = access(path, mode);
1015 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001016 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001017}
1018
Guido van Rossumd371ff11999-01-25 16:12:23 +00001019#ifndef F_OK
1020#define F_OK 0
1021#endif
1022#ifndef R_OK
1023#define R_OK 4
1024#endif
1025#ifndef W_OK
1026#define W_OK 2
1027#endif
1028#ifndef X_OK
1029#define X_OK 1
1030#endif
1031
1032#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001033PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001034"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001035Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001036
1037static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001038posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001039{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001040 int id;
1041 char *ret;
1042
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001043 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001044 return NULL;
1045
Guido van Rossum94f6f721999-01-06 18:42:14 +00001046 ret = ttyname(id);
1047 if (ret == NULL)
1048 return(posix_error());
1049 return(PyString_FromString(ret));
1050}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001051#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001052
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001053#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001054PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001055"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001056Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001057
1058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001059posix_ctermid(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001060{
1061 char *ret;
1062 char buffer[L_ctermid];
1063
1064 if (!PyArg_ParseTuple(args, ":ctermid"))
1065 return NULL;
1066
Greg Wardb48bc172000-03-01 21:51:56 +00001067#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001068 ret = ctermid_r(buffer);
1069#else
1070 ret = ctermid(buffer);
1071#endif
1072 if (ret == NULL)
1073 return(posix_error());
1074 return(PyString_FromString(buffer));
1075}
1076#endif
1077
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001078PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001079"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001080Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001081
Barry Warsaw53699e91996-12-10 23:23:01 +00001082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001083posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001084{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001085#ifdef MS_WINDOWS
1086 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1087#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1088 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001089#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001090 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001091#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001092}
1093
Fred Drake4d1e64b2002-04-15 19:40:07 +00001094#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001095PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001096"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001097Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001098opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001099
1100static PyObject *
1101posix_fchdir(PyObject *self, PyObject *fdobj)
1102{
1103 return posix_fildes(fdobj, fchdir);
1104}
1105#endif /* HAVE_FCHDIR */
1106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001108PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001109"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001110Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001111
Barry Warsaw53699e91996-12-10 23:23:01 +00001112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001113posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001114{
Mark Hammondef8b6542001-05-13 08:04:26 +00001115 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001116 int i;
1117 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001118 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001119 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001120 return NULL;
1121 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001122 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001123 Py_END_ALLOW_THREADS
1124 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001125 return posix_error_with_allocated_filename(path);
1126 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001127 Py_INCREF(Py_None);
1128 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001129}
1130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001131
Martin v. Löwis244edc82001-10-04 22:44:26 +00001132#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001133PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001134"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001135Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001136
1137static PyObject *
1138posix_chroot(PyObject *self, PyObject *args)
1139{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001140 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001141}
1142#endif
1143
Guido van Rossum21142a01999-01-08 21:05:37 +00001144#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001145PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001146"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001147force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001148
1149static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001150posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001151{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001152 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001153}
1154#endif /* HAVE_FSYNC */
1155
1156#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001157
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001158#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001159extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1160#endif
1161
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001162PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001163"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001164force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001165 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001166
1167static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001168posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001169{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001170 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001171}
1172#endif /* HAVE_FDATASYNC */
1173
1174
Fredrik Lundh10723342000-07-10 16:38:09 +00001175#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001176PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001177"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001178Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001179
Barry Warsaw53699e91996-12-10 23:23:01 +00001180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001181posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001182{
Mark Hammondef8b6542001-05-13 08:04:26 +00001183 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001184 int uid, gid;
1185 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001186 if (!PyArg_ParseTuple(args, "etii:chown",
1187 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001188 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001189 return NULL;
1190 Py_BEGIN_ALLOW_THREADS
1191 res = chown(path, (uid_t) uid, (gid_t) gid);
1192 Py_END_ALLOW_THREADS
1193 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001194 return posix_error_with_allocated_filename(path);
1195 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001196 Py_INCREF(Py_None);
1197 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001198}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001199#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001200
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001201#ifdef HAVE_LCHOWN
1202PyDoc_STRVAR(posix_lchown__doc__,
1203"lchown(path, uid, gid)\n\n\
1204Change the owner and group id of path to the numeric uid and gid.\n\
1205This function will not follow symbolic links.");
1206
1207static PyObject *
1208posix_lchown(PyObject *self, PyObject *args)
1209{
1210 char *path = NULL;
1211 int uid, gid;
1212 int res;
1213 if (!PyArg_ParseTuple(args, "etii:lchown",
1214 Py_FileSystemDefaultEncoding, &path,
1215 &uid, &gid))
1216 return NULL;
1217 Py_BEGIN_ALLOW_THREADS
1218 res = lchown(path, (uid_t) uid, (gid_t) gid);
1219 Py_END_ALLOW_THREADS
1220 if (res < 0)
1221 return posix_error_with_allocated_filename(path);
1222 PyMem_Free(path);
1223 Py_INCREF(Py_None);
1224 return Py_None;
1225}
1226#endif /* HAVE_LCHOWN */
1227
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001228
Guido van Rossum36bc6801995-06-14 22:54:23 +00001229#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001230PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001231"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001232Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001233
Barry Warsaw53699e91996-12-10 23:23:01 +00001234static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001235posix_getcwd(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001236{
1237 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001238 char *res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001239 if (!PyArg_ParseTuple(args, ":getcwd"))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001240 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001241 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001242#if defined(PYOS_OS2) && defined(PYCC_GCC)
1243 res = _getcwd2(buf, sizeof buf);
1244#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001245 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001246#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001247 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001248 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001250 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001251}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001252
1253PyDoc_STRVAR(posix_getcwdu__doc__,
1254"getcwdu() -> path\n\n\
1255Return a unicode string representing the current working directory.");
1256
1257static PyObject *
1258posix_getcwdu(PyObject *self, PyObject *args)
1259{
1260 char buf[1026];
1261 char *res;
1262 if (!PyArg_ParseTuple(args, ":getcwd"))
1263 return NULL;
1264
1265#ifdef Py_WIN_WIDE_FILENAMES
1266 if (unicode_file_names()) {
1267 wchar_t *wres;
1268 wchar_t wbuf[1026];
1269 Py_BEGIN_ALLOW_THREADS
1270 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1271 Py_END_ALLOW_THREADS
1272 if (wres == NULL)
1273 return posix_error();
1274 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1275 }
1276#endif
1277
1278 Py_BEGIN_ALLOW_THREADS
1279#if defined(PYOS_OS2) && defined(PYCC_GCC)
1280 res = _getcwd2(buf, sizeof buf);
1281#else
1282 res = getcwd(buf, sizeof buf);
1283#endif
1284 Py_END_ALLOW_THREADS
1285 if (res == NULL)
1286 return posix_error();
1287 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1288}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001289#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001290
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001291
Guido van Rossumb6775db1994-08-01 11:34:53 +00001292#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001293PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001294"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001295Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001296
Barry Warsaw53699e91996-12-10 23:23:01 +00001297static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001298posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001300 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001301}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001302#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001304
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001305PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001306"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001307Return a list containing the names of the entries in the directory.\n\
1308\n\
1309 path: path of directory to list\n\
1310\n\
1311The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001312entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001313
Barry Warsaw53699e91996-12-10 23:23:01 +00001314static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001315posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001316{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001317 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001318 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001319#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001320
Barry Warsaw53699e91996-12-10 23:23:01 +00001321 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001322 HANDLE hFindFile;
1323 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001324 /* MAX_PATH characters could mean a bigger encoded string */
1325 char namebuf[MAX_PATH*2+5];
1326 char *bufptr = namebuf;
1327 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001328
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001329#ifdef Py_WIN_WIDE_FILENAMES
1330 /* If on wide-character-capable OS see if argument
1331 is Unicode and if so use wide API. */
1332 if (unicode_file_names()) {
1333 PyUnicodeObject *po;
1334 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1335 WIN32_FIND_DATAW wFileData;
1336 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1337 Py_UNICODE wch;
1338 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1339 wnamebuf[MAX_PATH] = L'\0';
1340 len = wcslen(wnamebuf);
1341 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1342 if (wch != L'/' && wch != L'\\' && wch != L':')
1343 wnamebuf[len++] = L'/';
1344 wcscpy(wnamebuf + len, L"*.*");
1345 if ((d = PyList_New(0)) == NULL)
1346 return NULL;
1347 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1348 if (hFindFile == INVALID_HANDLE_VALUE) {
1349 errno = GetLastError();
1350 if (errno == ERROR_FILE_NOT_FOUND) {
1351 return d;
1352 }
1353 Py_DECREF(d);
1354 return win32_error_unicode("FindFirstFileW", wnamebuf);
1355 }
1356 do {
1357 if (wFileData.cFileName[0] == L'.' &&
1358 (wFileData.cFileName[1] == L'\0' ||
1359 wFileData.cFileName[1] == L'.' &&
1360 wFileData.cFileName[2] == L'\0'))
1361 continue;
1362 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1363 if (v == NULL) {
1364 Py_DECREF(d);
1365 d = NULL;
1366 break;
1367 }
1368 if (PyList_Append(d, v) != 0) {
1369 Py_DECREF(v);
1370 Py_DECREF(d);
1371 d = NULL;
1372 break;
1373 }
1374 Py_DECREF(v);
1375 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1376
1377 if (FindClose(hFindFile) == FALSE) {
1378 Py_DECREF(d);
1379 return win32_error_unicode("FindClose", wnamebuf);
1380 }
1381 return d;
1382 }
1383 /* Drop the argument parsing error as narrow strings
1384 are also valid. */
1385 PyErr_Clear();
1386 }
1387#endif
1388
Tim Peters5aa91602002-01-30 05:46:57 +00001389 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001390 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001391 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001392 if (len > 0) {
1393 char ch = namebuf[len-1];
1394 if (ch != SEP && ch != ALTSEP && ch != ':')
1395 namebuf[len++] = '/';
1396 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001397 strcpy(namebuf + len, "*.*");
1398
Barry Warsaw53699e91996-12-10 23:23:01 +00001399 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001400 return NULL;
1401
1402 hFindFile = FindFirstFile(namebuf, &FileData);
1403 if (hFindFile == INVALID_HANDLE_VALUE) {
1404 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001405 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001406 return d;
1407 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001408 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001409 }
1410 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001411 if (FileData.cFileName[0] == '.' &&
1412 (FileData.cFileName[1] == '\0' ||
1413 FileData.cFileName[1] == '.' &&
1414 FileData.cFileName[2] == '\0'))
1415 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001416 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001417 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001418 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001419 d = NULL;
1420 break;
1421 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001422 if (PyList_Append(d, v) != 0) {
1423 Py_DECREF(v);
1424 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001425 d = NULL;
1426 break;
1427 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001428 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001429 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1430
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001431 if (FindClose(hFindFile) == FALSE) {
1432 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001433 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001434 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001435
1436 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001437
Tim Peters0bb44a42000-09-15 07:44:49 +00001438#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001439
1440#ifndef MAX_PATH
1441#define MAX_PATH CCHMAXPATH
1442#endif
1443 char *name, *pt;
1444 int len;
1445 PyObject *d, *v;
1446 char namebuf[MAX_PATH+5];
1447 HDIR hdir = 1;
1448 ULONG srchcnt = 1;
1449 FILEFINDBUF3 ep;
1450 APIRET rc;
1451
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001452 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001453 return NULL;
1454 if (len >= MAX_PATH) {
1455 PyErr_SetString(PyExc_ValueError, "path too long");
1456 return NULL;
1457 }
1458 strcpy(namebuf, name);
1459 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001460 if (*pt == ALTSEP)
1461 *pt = SEP;
1462 if (namebuf[len-1] != SEP)
1463 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001464 strcpy(namebuf + len, "*.*");
1465
1466 if ((d = PyList_New(0)) == NULL)
1467 return NULL;
1468
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001469 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1470 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001471 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001472 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1473 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1474 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001475
1476 if (rc != NO_ERROR) {
1477 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001478 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001479 }
1480
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001481 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001482 do {
1483 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001484 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001485 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001486
1487 strcpy(namebuf, ep.achName);
1488
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001489 /* Leave Case of Name Alone -- In Native Form */
1490 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001491
1492 v = PyString_FromString(namebuf);
1493 if (v == NULL) {
1494 Py_DECREF(d);
1495 d = NULL;
1496 break;
1497 }
1498 if (PyList_Append(d, v) != 0) {
1499 Py_DECREF(v);
1500 Py_DECREF(d);
1501 d = NULL;
1502 break;
1503 }
1504 Py_DECREF(v);
1505 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1506 }
1507
1508 return d;
1509#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001510
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001511 char *name;
Barry Warsaw53699e91996-12-10 23:23:01 +00001512 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001513 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001514 struct dirent *ep;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001515 if (!PyArg_ParseTuple(args, "s:listdir", &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001516 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001517 if ((dirp = opendir(name)) == NULL) {
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001518 return posix_error_with_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001519 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001520 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001521 closedir(dirp);
1522 return NULL;
1523 }
1524 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001525 if (ep->d_name[0] == '.' &&
1526 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001527 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001528 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001529 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001530 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001531 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001532 d = NULL;
1533 break;
1534 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001535 if (PyList_Append(d, v) != 0) {
1536 Py_DECREF(v);
1537 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001538 d = NULL;
1539 break;
1540 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001541 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001542 }
1543 closedir(dirp);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001544
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001545 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001546
Tim Peters0bb44a42000-09-15 07:44:49 +00001547#endif /* which OS */
1548} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001549
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001550#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001551/* A helper function for abspath on win32 */
1552static PyObject *
1553posix__getfullpathname(PyObject *self, PyObject *args)
1554{
1555 /* assume encoded strings wont more than double no of chars */
1556 char inbuf[MAX_PATH*2];
1557 char *inbufp = inbuf;
1558 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1559 char outbuf[MAX_PATH*2];
1560 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001561#ifdef Py_WIN_WIDE_FILENAMES
1562 if (unicode_file_names()) {
1563 PyUnicodeObject *po;
1564 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1565 Py_UNICODE woutbuf[MAX_PATH*2];
1566 Py_UNICODE *wtemp;
1567 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1568 sizeof(woutbuf)/sizeof(woutbuf[0]),
1569 woutbuf, &wtemp))
1570 return win32_error("GetFullPathName", "");
1571 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1572 }
1573 /* Drop the argument parsing error as narrow strings
1574 are also valid. */
1575 PyErr_Clear();
1576 }
1577#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001578 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1579 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001580 &insize))
1581 return NULL;
1582 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1583 outbuf, &temp))
1584 return win32_error("GetFullPathName", inbuf);
1585 return PyString_FromString(outbuf);
1586} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001587#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001589PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001590"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001591Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001592
Barry Warsaw53699e91996-12-10 23:23:01 +00001593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001594posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001595{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001596 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001597 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001598 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001599
1600#ifdef Py_WIN_WIDE_FILENAMES
1601 if (unicode_file_names()) {
1602 PyUnicodeObject *po;
1603 if (PyArg_ParseTuple(args, "U|i:mkdir", &po)) {
1604 Py_BEGIN_ALLOW_THREADS
1605 /* PyUnicode_AS_UNICODE OK without thread lock as
1606 it is a simple dereference. */
1607 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1608 Py_END_ALLOW_THREADS
1609 if (res < 0)
1610 return posix_error();
1611 Py_INCREF(Py_None);
1612 return Py_None;
1613 }
1614 /* Drop the argument parsing error as narrow strings
1615 are also valid. */
1616 PyErr_Clear();
1617 }
1618#endif
1619
Tim Peters5aa91602002-01-30 05:46:57 +00001620 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001621 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001622 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001623 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001624#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001625 res = mkdir(path);
1626#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001627 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001628#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001629 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001630 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001631 return posix_error_with_allocated_filename(path);
1632 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001633 Py_INCREF(Py_None);
1634 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001635}
1636
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001637
Guido van Rossumb6775db1994-08-01 11:34:53 +00001638#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001639#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1640#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1641#include <sys/resource.h>
1642#endif
1643#endif
1644
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001645PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001646"nice(inc) -> new_priority\n\n\
1647Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001648
Barry Warsaw53699e91996-12-10 23:23:01 +00001649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001650posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001651{
1652 int increment, value;
1653
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001654 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001655 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001656
1657 /* There are two flavours of 'nice': one that returns the new
1658 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001659 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1660 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001661
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001662 If we are of the nice family that returns the new priority, we
1663 need to clear errno before the call, and check if errno is filled
1664 before calling posix_error() on a returnvalue of -1, because the
1665 -1 may be the actual new priority! */
1666
1667 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001668 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001669#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001670 if (value == 0)
1671 value = getpriority(PRIO_PROCESS, 0);
1672#endif
1673 if (value == -1 && errno != 0)
1674 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001675 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001676 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001677}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001678#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001679
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001680
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001681PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001682"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001683Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001684
Barry Warsaw53699e91996-12-10 23:23:01 +00001685static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001686posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001687{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001688#ifdef MS_WINDOWS
1689 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1690#else
1691 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1692#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001693}
1694
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001695
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001696PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001697"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001698Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001699
Barry Warsaw53699e91996-12-10 23:23:01 +00001700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001701posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001702{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001703#ifdef MS_WINDOWS
1704 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1705#else
1706 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1707#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001708}
1709
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001710
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001711PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001712"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001713Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001714
Barry Warsaw53699e91996-12-10 23:23:01 +00001715static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001716posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001717{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001718#ifdef MS_WINDOWS
1719 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1720#else
1721 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1722#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001723}
1724
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001725
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001726#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001727PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001728"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001729Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001730
Barry Warsaw53699e91996-12-10 23:23:01 +00001731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001732posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001733{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001734 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001735 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001736 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001737 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001738 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001739 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001740 Py_END_ALLOW_THREADS
1741 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001742}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001743#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001744
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001745
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001746PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001747"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001748Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001749
Barry Warsaw53699e91996-12-10 23:23:01 +00001750static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001751posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001752{
1753 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001754 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001755 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001756 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001757 if (i < 0)
1758 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001759 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001760}
1761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001762
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001763PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001764"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001765Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001766
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001768"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001769Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001770
Barry Warsaw53699e91996-12-10 23:23:01 +00001771static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001772posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001773{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001774#ifdef MS_WINDOWS
1775 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1776#else
1777 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1778#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001779}
1780
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001781
Guido van Rossumb6775db1994-08-01 11:34:53 +00001782#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001783PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001784"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001785Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001786
Barry Warsaw53699e91996-12-10 23:23:01 +00001787static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001788posix_uname(PyObject *self, PyObject *args)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001789{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001790 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001791 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001792 if (!PyArg_ParseTuple(args, ":uname"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00001793 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001794 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001795 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001796 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001797 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001798 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001799 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001800 u.sysname,
1801 u.nodename,
1802 u.release,
1803 u.version,
1804 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001805}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001806#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001807
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001808static int
1809extract_time(PyObject *t, long* sec, long* usec)
1810{
1811 long intval;
1812 if (PyFloat_Check(t)) {
1813 double tval = PyFloat_AsDouble(t);
1814 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1815 if (!intobj)
1816 return -1;
1817 intval = PyInt_AsLong(intobj);
1818 Py_DECREF(intobj);
1819 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001820 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001821 if (*usec < 0)
1822 /* If rounding gave us a negative number,
1823 truncate. */
1824 *usec = 0;
1825 return 0;
1826 }
1827 intval = PyInt_AsLong(t);
1828 if (intval == -1 && PyErr_Occurred())
1829 return -1;
1830 *sec = intval;
1831 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001832 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001833}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001834
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001835PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001836"utime(path, (atime, utime))\n\
1837utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001838Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001840
Barry Warsaw53699e91996-12-10 23:23:01 +00001841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001842posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001843{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001844 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001845 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001846 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001847 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001848
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001849#if defined(HAVE_UTIMES)
1850 struct timeval buf[2];
1851#define ATIME buf[0].tv_sec
1852#define MTIME buf[1].tv_sec
1853#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001854/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001855 struct utimbuf buf;
1856#define ATIME buf.actime
1857#define MTIME buf.modtime
1858#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001859#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001860 time_t buf[2];
1861#define ATIME buf[0]
1862#define MTIME buf[1]
1863#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001864#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001865
Barry Warsaw3cef8562000-05-01 16:17:24 +00001866 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001867 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001868 if (arg == Py_None) {
1869 /* optional time values not given */
1870 Py_BEGIN_ALLOW_THREADS
1871 res = utime(path, NULL);
1872 Py_END_ALLOW_THREADS
1873 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001874 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00001875 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001876 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00001877 return NULL;
1878 }
1879 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001880 if (extract_time(PyTuple_GET_ITEM(arg, 0),
1881 &atime, &ausec) == -1)
1882 return NULL;
1883 if (extract_time(PyTuple_GET_ITEM(arg, 1),
1884 &mtime, &musec) == -1)
1885 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001886 ATIME = atime;
1887 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001888#ifdef HAVE_UTIMES
1889 buf[0].tv_usec = ausec;
1890 buf[1].tv_usec = musec;
1891 Py_BEGIN_ALLOW_THREADS
1892 res = utimes(path, buf);
1893 Py_END_ALLOW_THREADS
1894#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00001895 Py_BEGIN_ALLOW_THREADS
1896 res = utime(path, UTIME_ARG);
1897 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001898#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00001899 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00001900 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00001901 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001902 Py_INCREF(Py_None);
1903 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001904#undef UTIME_ARG
1905#undef ATIME
1906#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001907}
1908
Guido van Rossum85e3b011991-06-03 12:42:10 +00001909
Guido van Rossum3b066191991-06-04 19:40:25 +00001910/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001911
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001912PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001913"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001914Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001915
Barry Warsaw53699e91996-12-10 23:23:01 +00001916static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001917posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001918{
1919 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001920 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001921 return NULL;
1922 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00001923 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00001924}
1925
Martin v. Löwis114619e2002-10-07 06:44:21 +00001926#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
1927static void
1928free_string_array(char **array, int count)
1929{
1930 int i;
1931 for (i = 0; i < count; i++)
1932 PyMem_Free(array[i]);
1933 PyMem_DEL(array);
1934}
1935#endif
1936
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001937
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001938#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001939PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001940"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001941Execute an executable path with arguments, replacing current process.\n\
1942\n\
1943 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001944 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001945
Barry Warsaw53699e91996-12-10 23:23:01 +00001946static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001947posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00001948{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001949 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00001950 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001951 char **argvlist;
1952 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001953 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001954
Guido van Rossum89b33251993-10-22 14:26:06 +00001955 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00001956 argv is a list or tuple of strings. */
1957
Martin v. Löwis114619e2002-10-07 06:44:21 +00001958 if (!PyArg_ParseTuple(args, "etO:execv",
1959 Py_FileSystemDefaultEncoding,
1960 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00001961 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001962 if (PyList_Check(argv)) {
1963 argc = PyList_Size(argv);
1964 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001965 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001966 else if (PyTuple_Check(argv)) {
1967 argc = PyTuple_Size(argv);
1968 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00001969 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001970 else {
Fred Drake661ea262000-10-24 19:57:45 +00001971 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001972 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00001973 return NULL;
1974 }
1975
1976 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00001977 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001978 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001979 return NULL;
1980 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001981
Barry Warsaw53699e91996-12-10 23:23:01 +00001982 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00001983 if (argvlist == NULL) {
1984 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00001985 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00001986 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001987 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00001988 if (!PyArg_Parse((*getitem)(argv, i), "et",
1989 Py_FileSystemDefaultEncoding,
1990 &argvlist[i])) {
1991 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00001992 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00001993 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00001994 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00001995 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00001996
Guido van Rossum85e3b011991-06-03 12:42:10 +00001997 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00001998 }
1999 argvlist[argc] = NULL;
2000
Guido van Rossumb6775db1994-08-01 11:34:53 +00002001#ifdef BAD_EXEC_PROTOTYPES
2002 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002003#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002004 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002005#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002006
Guido van Rossum85e3b011991-06-03 12:42:10 +00002007 /* If we get here it's definitely an error */
2008
Martin v. Löwis114619e2002-10-07 06:44:21 +00002009 free_string_array(argvlist, argc);
2010 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002011 return posix_error();
2012}
2013
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002015PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002016"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002017Execute a path with arguments and environment, replacing current process.\n\
2018\n\
2019 path: path of executable file\n\
2020 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002021 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002022
Barry Warsaw53699e91996-12-10 23:23:01 +00002023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002024posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002025{
2026 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002027 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002028 char **argvlist;
2029 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002030 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002031 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002032 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002033 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002034
2035 /* execve has three arguments: (path, argv, env), where
2036 argv is a list or tuple of strings and env is a dictionary
2037 like posix.environ. */
2038
Martin v. Löwis114619e2002-10-07 06:44:21 +00002039 if (!PyArg_ParseTuple(args, "etOO:execve",
2040 Py_FileSystemDefaultEncoding,
2041 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002042 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002043 if (PyList_Check(argv)) {
2044 argc = PyList_Size(argv);
2045 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002046 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002047 else if (PyTuple_Check(argv)) {
2048 argc = PyTuple_Size(argv);
2049 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002050 }
2051 else {
Fred Drake661ea262000-10-24 19:57:45 +00002052 PyErr_SetString(PyExc_TypeError, "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002053 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002054 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002055 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00002056 PyErr_SetString(PyExc_TypeError, "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002057 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002058 }
2059
Guido van Rossum50422b42000-04-26 20:34:28 +00002060 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002061 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002062 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002063 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002064 }
2065
Barry Warsaw53699e91996-12-10 23:23:01 +00002066 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002067 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002068 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002069 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002070 }
2071 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002072 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002073 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002074 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002075 &argvlist[i]))
2076 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002077 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002078 goto fail_1;
2079 }
2080 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002081 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002082 argvlist[argc] = NULL;
2083
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002084 i = PyMapping_Size(env);
Barry Warsaw53699e91996-12-10 23:23:01 +00002085 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002086 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002087 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002088 goto fail_1;
2089 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002090 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002091 keys = PyMapping_Keys(env);
2092 vals = PyMapping_Values(env);
2093 if (!keys || !vals)
2094 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002095
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002096 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002097 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002098 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002099
2100 key = PyList_GetItem(keys, pos);
2101 val = PyList_GetItem(vals, pos);
2102 if (!key || !val)
2103 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002104
Fred Drake661ea262000-10-24 19:57:45 +00002105 if (!PyArg_Parse(key, "s;execve() arg 3 contains a non-string key", &k) ||
2106 !PyArg_Parse(val, "s;execve() arg 3 contains a non-string value", &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002107 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002108 goto fail_2;
2109 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002110
2111#if defined(PYOS_OS2)
2112 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2113 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2114#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002115 len = PyString_Size(key) + PyString_Size(val) + 2;
2116 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002117 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002118 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002119 goto fail_2;
2120 }
Tim Petersc8996f52001-12-03 20:41:00 +00002121 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002122 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002123#if defined(PYOS_OS2)
2124 }
2125#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002126 }
2127 envlist[envc] = 0;
2128
Guido van Rossumb6775db1994-08-01 11:34:53 +00002129
2130#ifdef BAD_EXEC_PROTOTYPES
2131 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002132#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002133 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002134#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002135
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002136 /* If we get here it's definitely an error */
2137
2138 (void) posix_error();
2139
2140 fail_2:
2141 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002142 PyMem_DEL(envlist[envc]);
2143 PyMem_DEL(envlist);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002144 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002145 free_string_array(argvlist,lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002146 Py_XDECREF(vals);
2147 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002148 fail_0:
2149 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002150 return NULL;
2151}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002152#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002154
Guido van Rossuma1065681999-01-25 23:20:23 +00002155#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002156PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002157"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002158Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002159\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002160 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002161 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002162 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002163
2164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002165posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002166{
2167 char *path;
2168 PyObject *argv;
2169 char **argvlist;
2170 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002171 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002172 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002173
2174 /* spawnv has three arguments: (mode, path, argv), where
2175 argv is a list or tuple of strings. */
2176
Martin v. Löwis114619e2002-10-07 06:44:21 +00002177 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2178 Py_FileSystemDefaultEncoding,
2179 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002180 return NULL;
2181 if (PyList_Check(argv)) {
2182 argc = PyList_Size(argv);
2183 getitem = PyList_GetItem;
2184 }
2185 else if (PyTuple_Check(argv)) {
2186 argc = PyTuple_Size(argv);
2187 getitem = PyTuple_GetItem;
2188 }
2189 else {
Martin v. Löwise75f0e42001-11-24 09:31:44 +00002190 PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002191 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002192 return NULL;
2193 }
2194
2195 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002196 if (argvlist == NULL) {
2197 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002198 return NULL;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002199 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002200 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002201 if (!PyArg_Parse((*getitem)(argv, i), "et",
2202 Py_FileSystemDefaultEncoding,
2203 &argvlist[i])) {
2204 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002205 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002206 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002207 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002208 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002209 }
2210 }
2211 argvlist[argc] = NULL;
2212
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002213#if defined(PYOS_OS2) && defined(PYCC_GCC)
2214 Py_BEGIN_ALLOW_THREADS
2215 spawnval = spawnv(mode, path, argvlist);
2216 Py_END_ALLOW_THREADS
2217#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002218 if (mode == _OLD_P_OVERLAY)
2219 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002220
Tim Peters25059d32001-12-07 20:35:43 +00002221 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002222 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002223 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002224#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002225
Martin v. Löwis114619e2002-10-07 06:44:21 +00002226 free_string_array(argvlist, argc);
2227 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002228
Fred Drake699f3522000-06-29 21:12:41 +00002229 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002230 return posix_error();
2231 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002232#if SIZEOF_LONG == SIZEOF_VOID_P
2233 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002234#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002235 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002236#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002237}
2238
2239
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002240PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002241"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002242Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002243\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002244 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002245 path: path of executable file\n\
2246 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002247 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002248
2249static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002250posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002251{
2252 char *path;
2253 PyObject *argv, *env;
2254 char **argvlist;
2255 char **envlist;
2256 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2257 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002258 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002259 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002260 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002261
2262 /* spawnve has four arguments: (mode, path, argv, env), where
2263 argv is a list or tuple of strings and env is a dictionary
2264 like posix.environ. */
2265
Martin v. Löwis114619e2002-10-07 06:44:21 +00002266 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2267 Py_FileSystemDefaultEncoding,
2268 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002269 return NULL;
2270 if (PyList_Check(argv)) {
2271 argc = PyList_Size(argv);
2272 getitem = PyList_GetItem;
2273 }
2274 else if (PyTuple_Check(argv)) {
2275 argc = PyTuple_Size(argv);
2276 getitem = PyTuple_GetItem;
2277 }
2278 else {
Fred Drake661ea262000-10-24 19:57:45 +00002279 PyErr_SetString(PyExc_TypeError, "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002280 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002281 }
2282 if (!PyMapping_Check(env)) {
Fred Drake661ea262000-10-24 19:57:45 +00002283 PyErr_SetString(PyExc_TypeError, "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002284 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002285 }
2286
2287 argvlist = PyMem_NEW(char *, argc+1);
2288 if (argvlist == NULL) {
2289 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002290 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002291 }
2292 for (i = 0; i < argc; i++) {
2293 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002294 "et;spawnve() arg 2 must contain only strings",
2295 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002296 &argvlist[i]))
2297 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002298 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002299 goto fail_1;
2300 }
2301 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002302 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002303 argvlist[argc] = NULL;
2304
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002305 i = PyMapping_Size(env);
Guido van Rossuma1065681999-01-25 23:20:23 +00002306 envlist = PyMem_NEW(char *, i + 1);
2307 if (envlist == NULL) {
2308 PyErr_NoMemory();
2309 goto fail_1;
2310 }
2311 envc = 0;
2312 keys = PyMapping_Keys(env);
2313 vals = PyMapping_Values(env);
2314 if (!keys || !vals)
2315 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002316
Guido van Rossuma1065681999-01-25 23:20:23 +00002317 for (pos = 0; pos < i; pos++) {
2318 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002319 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002320
2321 key = PyList_GetItem(keys, pos);
2322 val = PyList_GetItem(vals, pos);
2323 if (!key || !val)
2324 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002325
Fred Drake661ea262000-10-24 19:57:45 +00002326 if (!PyArg_Parse(key, "s;spawnve() arg 3 contains a non-string key", &k) ||
2327 !PyArg_Parse(val, "s;spawnve() arg 3 contains a non-string value", &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002328 {
2329 goto fail_2;
2330 }
Tim Petersc8996f52001-12-03 20:41:00 +00002331 len = PyString_Size(key) + PyString_Size(val) + 2;
2332 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002333 if (p == NULL) {
2334 PyErr_NoMemory();
2335 goto fail_2;
2336 }
Tim Petersc8996f52001-12-03 20:41:00 +00002337 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002338 envlist[envc++] = p;
2339 }
2340 envlist[envc] = 0;
2341
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002342#if defined(PYOS_OS2) && defined(PYCC_GCC)
2343 Py_BEGIN_ALLOW_THREADS
2344 spawnval = spawnve(mode, path, argvlist, envlist);
2345 Py_END_ALLOW_THREADS
2346#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002347 if (mode == _OLD_P_OVERLAY)
2348 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002349
2350 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002351 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002352 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002353#endif
Tim Peters25059d32001-12-07 20:35:43 +00002354
Fred Drake699f3522000-06-29 21:12:41 +00002355 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002356 (void) posix_error();
2357 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002358#if SIZEOF_LONG == SIZEOF_VOID_P
2359 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002360#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002361 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002362#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002363
2364 fail_2:
2365 while (--envc >= 0)
2366 PyMem_DEL(envlist[envc]);
2367 PyMem_DEL(envlist);
2368 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002369 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002370 Py_XDECREF(vals);
2371 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002372 fail_0:
2373 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002374 return res;
2375}
2376#endif /* HAVE_SPAWNV */
2377
2378
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002379#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002380PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002381"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002382Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2383\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002385
2386static PyObject *
2387posix_fork1(self, args)
2388 PyObject *self;
2389 PyObject *args;
2390{
2391 int pid;
2392 if (!PyArg_ParseTuple(args, ":fork1"))
2393 return NULL;
2394 pid = fork1();
2395 if (pid == -1)
2396 return posix_error();
2397 PyOS_AfterFork();
2398 return PyInt_FromLong((long)pid);
2399}
2400#endif
2401
2402
Guido van Rossumad0ee831995-03-01 10:34:45 +00002403#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002404PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002405"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002406Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002407Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002408
Barry Warsaw53699e91996-12-10 23:23:01 +00002409static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002410posix_fork(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002411{
2412 int pid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002413 if (!PyArg_ParseTuple(args, ":fork"))
Guido van Rossum50e61dc1992-03-27 17:22:31 +00002414 return NULL;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002415 pid = fork();
2416 if (pid == -1)
2417 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002418 if (pid == 0)
2419 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002420 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002421}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002422#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002423
Fred Drake8cef4cf2000-06-28 16:40:38 +00002424#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
2425#ifdef HAVE_PTY_H
2426#include <pty.h>
2427#else
2428#ifdef HAVE_LIBUTIL_H
2429#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002430#endif /* HAVE_LIBUTIL_H */
2431#endif /* HAVE_PTY_H */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002432#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002433
Thomas Wouters70c21a12000-07-14 14:28:33 +00002434#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002435PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002436"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002437Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002438
2439static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002440posix_openpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002441{
2442 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002443#ifndef HAVE_OPENPTY
2444 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002445#endif
2446
Fred Drake8cef4cf2000-06-28 16:40:38 +00002447 if (!PyArg_ParseTuple(args, ":openpty"))
2448 return NULL;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002449
2450#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002451 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2452 return posix_error();
Thomas Wouters70c21a12000-07-14 14:28:33 +00002453#else
2454 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2455 if (slave_name == NULL)
2456 return posix_error();
2457
2458 slave_fd = open(slave_name, O_RDWR);
2459 if (slave_fd < 0)
2460 return posix_error();
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002461#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002462
Fred Drake8cef4cf2000-06-28 16:40:38 +00002463 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002464
Fred Drake8cef4cf2000-06-28 16:40:38 +00002465}
Thomas Wouters70c21a12000-07-14 14:28:33 +00002466#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002467
2468#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002469PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002470"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002471Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2472Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002473To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002474
2475static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002476posix_forkpty(PyObject *self, PyObject *args)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002477{
2478 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002479
Fred Drake8cef4cf2000-06-28 16:40:38 +00002480 if (!PyArg_ParseTuple(args, ":forkpty"))
2481 return NULL;
2482 pid = forkpty(&master_fd, NULL, NULL, NULL);
2483 if (pid == -1)
2484 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002485 if (pid == 0)
2486 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002487 return Py_BuildValue("(ii)", pid, master_fd);
2488}
2489#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002490
Guido van Rossumad0ee831995-03-01 10:34:45 +00002491#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002492PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002493"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002494Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002495
Barry Warsaw53699e91996-12-10 23:23:01 +00002496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002497posix_getegid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002498{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002499 if (!PyArg_ParseTuple(args, ":getegid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002500 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002501 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002502}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002503#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002504
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002505
Guido van Rossumad0ee831995-03-01 10:34:45 +00002506#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002507PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002508"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002509Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002510
Barry Warsaw53699e91996-12-10 23:23:01 +00002511static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002512posix_geteuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002513{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002514 if (!PyArg_ParseTuple(args, ":geteuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002515 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002516 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002517}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002518#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002519
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002520
Guido van Rossumad0ee831995-03-01 10:34:45 +00002521#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002522PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002523"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002524Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002525
Barry Warsaw53699e91996-12-10 23:23:01 +00002526static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002527posix_getgid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002528{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002529 if (!PyArg_ParseTuple(args, ":getgid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002530 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002531 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002532}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002533#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002534
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002535
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002536PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002537"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002538Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002539
Barry Warsaw53699e91996-12-10 23:23:01 +00002540static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002541posix_getpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002542{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002543 if (!PyArg_ParseTuple(args, ":getpid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002544 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002545 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002546}
2547
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002548
Fred Drakec9680921999-12-13 16:37:25 +00002549#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002550PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002551"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002552Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002553
2554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002555posix_getgroups(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00002556{
2557 PyObject *result = NULL;
2558
2559 if (PyArg_ParseTuple(args, ":getgroups")) {
2560#ifdef NGROUPS_MAX
2561#define MAX_GROUPS NGROUPS_MAX
2562#else
2563 /* defined to be 16 on Solaris7, so this should be a small number */
2564#define MAX_GROUPS 64
2565#endif
2566 gid_t grouplist[MAX_GROUPS];
2567 int n;
2568
2569 n = getgroups(MAX_GROUPS, grouplist);
2570 if (n < 0)
2571 posix_error();
2572 else {
2573 result = PyList_New(n);
2574 if (result != NULL) {
2575 PyObject *o;
2576 int i;
2577 for (i = 0; i < n; ++i) {
2578 o = PyInt_FromLong((long)grouplist[i]);
2579 if (o == NULL) {
2580 Py_DECREF(result);
2581 result = NULL;
2582 break;
2583 }
2584 PyList_SET_ITEM(result, i, o);
2585 }
2586 }
2587 }
2588 }
2589 return result;
2590}
2591#endif
2592
Martin v. Löwis606edc12002-06-13 21:09:11 +00002593#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002594PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002595"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002596Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002597
2598static PyObject *
2599posix_getpgid(PyObject *self, PyObject *args)
2600{
2601 int pid, pgid;
2602 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2603 return NULL;
2604 pgid = getpgid(pid);
2605 if (pgid < 0)
2606 return posix_error();
2607 return PyInt_FromLong((long)pgid);
2608}
2609#endif /* HAVE_GETPGID */
2610
2611
Guido van Rossumb6775db1994-08-01 11:34:53 +00002612#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002613PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002614"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002615Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002616
Barry Warsaw53699e91996-12-10 23:23:01 +00002617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002618posix_getpgrp(PyObject *self, PyObject *args)
Guido van Rossum04814471991-06-04 20:23:49 +00002619{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002620 if (!PyArg_ParseTuple(args, ":getpgrp"))
Guido van Rossum04814471991-06-04 20:23:49 +00002621 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002622#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002623 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002624#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002625 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002626#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002627}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002628#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002629
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002630
Guido van Rossumb6775db1994-08-01 11:34:53 +00002631#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002632PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002633"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002634Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002635
Barry Warsaw53699e91996-12-10 23:23:01 +00002636static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002637posix_setpgrp(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002638{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002639 if (!PyArg_ParseTuple(args, ":setpgrp"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00002640 return NULL;
Guido van Rossum64933891994-10-20 21:56:42 +00002641#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002642 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002643#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002644 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002645#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002646 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002647 Py_INCREF(Py_None);
2648 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002649}
2650
Guido van Rossumb6775db1994-08-01 11:34:53 +00002651#endif /* HAVE_SETPGRP */
2652
Guido van Rossumad0ee831995-03-01 10:34:45 +00002653#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002654PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002655"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002656Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002657
Barry Warsaw53699e91996-12-10 23:23:01 +00002658static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00002659posix_getppid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002660{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002661 if (!PyArg_ParseTuple(args, ":getppid"))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002662 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002663 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002664}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002665#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002666
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002667
Fred Drake12c6e2d1999-12-14 21:25:03 +00002668#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002669PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002670"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002671Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002672
2673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002674posix_getlogin(PyObject *self, PyObject *args)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002675{
2676 PyObject *result = NULL;
2677
2678 if (PyArg_ParseTuple(args, ":getlogin")) {
Fred Drakea30680b2000-12-06 21:24:28 +00002679 char *name;
2680 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002681
Fred Drakea30680b2000-12-06 21:24:28 +00002682 errno = 0;
2683 name = getlogin();
2684 if (name == NULL) {
2685 if (errno)
2686 posix_error();
2687 else
2688 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002689 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002690 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002691 else
2692 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002693 errno = old_errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002694 }
2695 return result;
2696}
2697#endif
2698
Guido van Rossumad0ee831995-03-01 10:34:45 +00002699#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002700PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002701"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002702Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002703
Barry Warsaw53699e91996-12-10 23:23:01 +00002704static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002705posix_getuid(PyObject *self, PyObject *args)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002706{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002707 if (!PyArg_ParseTuple(args, ":getuid"))
Guido van Rossum46003ff1992-05-15 11:05:24 +00002708 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002709 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002710}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002711#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002712
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002713
Guido van Rossumad0ee831995-03-01 10:34:45 +00002714#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002715PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002716"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002717Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002718
Barry Warsaw53699e91996-12-10 23:23:01 +00002719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002720posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002721{
2722 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002723 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002724 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002725#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002726 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2727 APIRET rc;
2728 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002729 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002730
2731 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2732 APIRET rc;
2733 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002734 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002735
2736 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002737 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002738#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002739 if (kill(pid, sig) == -1)
2740 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002741#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002742 Py_INCREF(Py_None);
2743 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002744}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002745#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002746
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002747#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002748PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002749"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002750Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002751
2752static PyObject *
2753posix_killpg(PyObject *self, PyObject *args)
2754{
2755 int pgid, sig;
2756 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2757 return NULL;
2758 if (killpg(pgid, sig) == -1)
2759 return posix_error();
2760 Py_INCREF(Py_None);
2761 return Py_None;
2762}
2763#endif
2764
Guido van Rossumc0125471996-06-28 18:55:32 +00002765#ifdef HAVE_PLOCK
2766
2767#ifdef HAVE_SYS_LOCK_H
2768#include <sys/lock.h>
2769#endif
2770
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002771PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002772"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002773Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002774
Barry Warsaw53699e91996-12-10 23:23:01 +00002775static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002776posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002777{
2778 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002779 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002780 return NULL;
2781 if (plock(op) == -1)
2782 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002783 Py_INCREF(Py_None);
2784 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002785}
2786#endif
2787
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002788
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002789#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002790PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002791"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002792Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002793
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002794#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002795#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002796static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002797async_system(const char *command)
2798{
2799 char *p, errormsg[256], args[1024];
2800 RESULTCODES rcodes;
2801 APIRET rc;
2802 char *shell = getenv("COMSPEC");
2803 if (!shell)
2804 shell = "cmd";
2805
2806 strcpy(args, shell);
2807 p = &args[ strlen(args)+1 ];
2808 strcpy(p, "/c ");
2809 strcat(p, command);
2810 p += strlen(p) + 1;
2811 *p = '\0';
2812
2813 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002814 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002815 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002816 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002817 &rcodes, shell);
2818 return rc;
2819}
2820
Guido van Rossumd48f2521997-12-05 22:19:34 +00002821static FILE *
2822popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002823{
2824 HFILE rhan, whan;
2825 FILE *retfd = NULL;
2826 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2827
Guido van Rossumd48f2521997-12-05 22:19:34 +00002828 if (rc != NO_ERROR) {
2829 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002830 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002831 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002832
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002833 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2834 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002835
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002836 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2837 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002838
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002839 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2840 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002841
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002842 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002843 }
2844
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002845 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
2846 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002847
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002848 if (rc == NO_ERROR)
2849 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2850
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002851 close(oldfd); /* And Close Saved STDOUT Handle */
2852 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002853
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002854 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2855 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002856
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002857 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2858 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002859
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002860 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2861 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002862
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002863 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002864 }
2865
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002866 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
2867 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002868
Martin v. Löwisdedbe252001-11-02 23:59:11 +00002869 if (rc == NO_ERROR)
2870 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2871
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002872 close(oldfd); /* And Close Saved STDIN Handle */
2873 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002874
Guido van Rossumd48f2521997-12-05 22:19:34 +00002875 } else {
2876 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002877 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002878 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002879}
2880
2881static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002882posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002883{
2884 char *name;
2885 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00002886 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002887 FILE *fp;
2888 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002889 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002890 return NULL;
2891 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00002892 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002893 Py_END_ALLOW_THREADS
2894 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002895 return os2_error(err);
2896
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002897 f = PyFile_FromFile(fp, name, mode, fclose);
2898 if (f != NULL)
2899 PyFile_SetBufSize(f, bufsize);
2900 return f;
2901}
2902
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002903#elif defined(PYCC_GCC)
2904
2905/* standard posix version of popen() support */
2906static PyObject *
2907posix_popen(PyObject *self, PyObject *args)
2908{
2909 char *name;
2910 char *mode = "r";
2911 int bufsize = -1;
2912 FILE *fp;
2913 PyObject *f;
2914 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2915 return NULL;
2916 Py_BEGIN_ALLOW_THREADS
2917 fp = popen(name, mode);
2918 Py_END_ALLOW_THREADS
2919 if (fp == NULL)
2920 return posix_error();
2921 f = PyFile_FromFile(fp, name, mode, pclose);
2922 if (f != NULL)
2923 PyFile_SetBufSize(f, bufsize);
2924 return f;
2925}
2926
2927/* fork() under OS/2 has lots'o'warts
2928 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
2929 * most of this code is a ripoff of the win32 code, but using the
2930 * capabilities of EMX's C library routines
2931 */
2932
2933/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
2934#define POPEN_1 1
2935#define POPEN_2 2
2936#define POPEN_3 3
2937#define POPEN_4 4
2938
2939static PyObject *_PyPopen(char *, int, int, int);
2940static int _PyPclose(FILE *file);
2941
2942/*
2943 * Internal dictionary mapping popen* file pointers to process handles,
2944 * for use when retrieving the process exit code. See _PyPclose() below
2945 * for more information on this dictionary's use.
2946 */
2947static PyObject *_PyPopenProcs = NULL;
2948
2949/* os2emx version of popen2()
2950 *
2951 * The result of this function is a pipe (file) connected to the
2952 * process's stdin, and a pipe connected to the process's stdout.
2953 */
2954
2955static PyObject *
2956os2emx_popen2(PyObject *self, PyObject *args)
2957{
2958 PyObject *f;
2959 int tm=0;
2960
2961 char *cmdstring;
2962 char *mode = "t";
2963 int bufsize = -1;
2964 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2965 return NULL;
2966
2967 if (*mode == 't')
2968 tm = O_TEXT;
2969 else if (*mode != 'b') {
2970 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2971 return NULL;
2972 } else
2973 tm = O_BINARY;
2974
2975 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
2976
2977 return f;
2978}
2979
2980/*
2981 * Variation on os2emx.popen2
2982 *
2983 * The result of this function is 3 pipes - the process's stdin,
2984 * stdout and stderr
2985 */
2986
2987static PyObject *
2988os2emx_popen3(PyObject *self, PyObject *args)
2989{
2990 PyObject *f;
2991 int tm = 0;
2992
2993 char *cmdstring;
2994 char *mode = "t";
2995 int bufsize = -1;
2996 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2997 return NULL;
2998
2999 if (*mode == 't')
3000 tm = O_TEXT;
3001 else if (*mode != 'b') {
3002 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3003 return NULL;
3004 } else
3005 tm = O_BINARY;
3006
3007 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3008
3009 return f;
3010}
3011
3012/*
3013 * Variation on os2emx.popen2
3014 *
3015 * The result of this function is 2 pipes - the processes stdin,
3016 * and stdout+stderr combined as a single pipe.
3017 */
3018
3019static PyObject *
3020os2emx_popen4(PyObject *self, PyObject *args)
3021{
3022 PyObject *f;
3023 int tm = 0;
3024
3025 char *cmdstring;
3026 char *mode = "t";
3027 int bufsize = -1;
3028 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3029 return NULL;
3030
3031 if (*mode == 't')
3032 tm = O_TEXT;
3033 else if (*mode != 'b') {
3034 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3035 return NULL;
3036 } else
3037 tm = O_BINARY;
3038
3039 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3040
3041 return f;
3042}
3043
3044/* a couple of structures for convenient handling of multiple
3045 * file handles and pipes
3046 */
3047struct file_ref
3048{
3049 int handle;
3050 int flags;
3051};
3052
3053struct pipe_ref
3054{
3055 int rd;
3056 int wr;
3057};
3058
3059/* The following code is derived from the win32 code */
3060
3061static PyObject *
3062_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3063{
3064 struct file_ref stdio[3];
3065 struct pipe_ref p_fd[3];
3066 FILE *p_s[3];
3067 int file_count, i, pipe_err, pipe_pid;
3068 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3069 PyObject *f, *p_f[3];
3070
3071 /* file modes for subsequent fdopen's on pipe handles */
3072 if (mode == O_TEXT)
3073 {
3074 rd_mode = "rt";
3075 wr_mode = "wt";
3076 }
3077 else
3078 {
3079 rd_mode = "rb";
3080 wr_mode = "wb";
3081 }
3082
3083 /* prepare shell references */
3084 if ((shell = getenv("EMXSHELL")) == NULL)
3085 if ((shell = getenv("COMSPEC")) == NULL)
3086 {
3087 errno = ENOENT;
3088 return posix_error();
3089 }
3090
3091 sh_name = _getname(shell);
3092 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3093 opt = "/c";
3094 else
3095 opt = "-c";
3096
3097 /* save current stdio fds + their flags, and set not inheritable */
3098 i = pipe_err = 0;
3099 while (pipe_err >= 0 && i < 3)
3100 {
3101 pipe_err = stdio[i].handle = dup(i);
3102 stdio[i].flags = fcntl(i, F_GETFD, 0);
3103 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3104 i++;
3105 }
3106 if (pipe_err < 0)
3107 {
3108 /* didn't get them all saved - clean up and bail out */
3109 int saved_err = errno;
3110 while (i-- > 0)
3111 {
3112 close(stdio[i].handle);
3113 }
3114 errno = saved_err;
3115 return posix_error();
3116 }
3117
3118 /* create pipe ends */
3119 file_count = 2;
3120 if (n == POPEN_3)
3121 file_count = 3;
3122 i = pipe_err = 0;
3123 while ((pipe_err == 0) && (i < file_count))
3124 pipe_err = pipe((int *)&p_fd[i++]);
3125 if (pipe_err < 0)
3126 {
3127 /* didn't get them all made - clean up and bail out */
3128 while (i-- > 0)
3129 {
3130 close(p_fd[i].wr);
3131 close(p_fd[i].rd);
3132 }
3133 errno = EPIPE;
3134 return posix_error();
3135 }
3136
3137 /* change the actual standard IO streams over temporarily,
3138 * making the retained pipe ends non-inheritable
3139 */
3140 pipe_err = 0;
3141
3142 /* - stdin */
3143 if (dup2(p_fd[0].rd, 0) == 0)
3144 {
3145 close(p_fd[0].rd);
3146 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3147 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3148 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3149 {
3150 close(p_fd[0].wr);
3151 pipe_err = -1;
3152 }
3153 }
3154 else
3155 {
3156 pipe_err = -1;
3157 }
3158
3159 /* - stdout */
3160 if (pipe_err == 0)
3161 {
3162 if (dup2(p_fd[1].wr, 1) == 1)
3163 {
3164 close(p_fd[1].wr);
3165 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3166 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3167 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3168 {
3169 close(p_fd[1].rd);
3170 pipe_err = -1;
3171 }
3172 }
3173 else
3174 {
3175 pipe_err = -1;
3176 }
3177 }
3178
3179 /* - stderr, as required */
3180 if (pipe_err == 0)
3181 switch (n)
3182 {
3183 case POPEN_3:
3184 {
3185 if (dup2(p_fd[2].wr, 2) == 2)
3186 {
3187 close(p_fd[2].wr);
3188 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3189 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3190 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3191 {
3192 close(p_fd[2].rd);
3193 pipe_err = -1;
3194 }
3195 }
3196 else
3197 {
3198 pipe_err = -1;
3199 }
3200 break;
3201 }
3202
3203 case POPEN_4:
3204 {
3205 if (dup2(1, 2) != 2)
3206 {
3207 pipe_err = -1;
3208 }
3209 break;
3210 }
3211 }
3212
3213 /* spawn the child process */
3214 if (pipe_err == 0)
3215 {
3216 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3217 if (pipe_pid == -1)
3218 {
3219 pipe_err = -1;
3220 }
3221 else
3222 {
3223 /* save the PID into the FILE structure
3224 * NOTE: this implementation doesn't actually
3225 * take advantage of this, but do it for
3226 * completeness - AIM Apr01
3227 */
3228 for (i = 0; i < file_count; i++)
3229 p_s[i]->_pid = pipe_pid;
3230 }
3231 }
3232
3233 /* reset standard IO to normal */
3234 for (i = 0; i < 3; i++)
3235 {
3236 dup2(stdio[i].handle, i);
3237 fcntl(i, F_SETFD, stdio[i].flags);
3238 close(stdio[i].handle);
3239 }
3240
3241 /* if any remnant problems, clean up and bail out */
3242 if (pipe_err < 0)
3243 {
3244 for (i = 0; i < 3; i++)
3245 {
3246 close(p_fd[i].rd);
3247 close(p_fd[i].wr);
3248 }
3249 errno = EPIPE;
3250 return posix_error_with_filename(cmdstring);
3251 }
3252
3253 /* build tuple of file objects to return */
3254 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3255 PyFile_SetBufSize(p_f[0], bufsize);
3256 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3257 PyFile_SetBufSize(p_f[1], bufsize);
3258 if (n == POPEN_3)
3259 {
3260 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3261 PyFile_SetBufSize(p_f[0], bufsize);
3262 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3263 }
3264 else
3265 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3266
3267 /*
3268 * Insert the files we've created into the process dictionary
3269 * all referencing the list with the process handle and the
3270 * initial number of files (see description below in _PyPclose).
3271 * Since if _PyPclose later tried to wait on a process when all
3272 * handles weren't closed, it could create a deadlock with the
3273 * child, we spend some energy here to try to ensure that we
3274 * either insert all file handles into the dictionary or none
3275 * at all. It's a little clumsy with the various popen modes
3276 * and variable number of files involved.
3277 */
3278 if (!_PyPopenProcs)
3279 {
3280 _PyPopenProcs = PyDict_New();
3281 }
3282
3283 if (_PyPopenProcs)
3284 {
3285 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3286 int ins_rc[3];
3287
3288 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3289 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3290
3291 procObj = PyList_New(2);
3292 pidObj = PyInt_FromLong((long) pipe_pid);
3293 intObj = PyInt_FromLong((long) file_count);
3294
3295 if (procObj && pidObj && intObj)
3296 {
3297 PyList_SetItem(procObj, 0, pidObj);
3298 PyList_SetItem(procObj, 1, intObj);
3299
3300 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3301 if (fileObj[0])
3302 {
3303 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3304 fileObj[0],
3305 procObj);
3306 }
3307 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3308 if (fileObj[1])
3309 {
3310 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3311 fileObj[1],
3312 procObj);
3313 }
3314 if (file_count >= 3)
3315 {
3316 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3317 if (fileObj[2])
3318 {
3319 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3320 fileObj[2],
3321 procObj);
3322 }
3323 }
3324
3325 if (ins_rc[0] < 0 || !fileObj[0] ||
3326 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3327 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3328 {
3329 /* Something failed - remove any dictionary
3330 * entries that did make it.
3331 */
3332 if (!ins_rc[0] && fileObj[0])
3333 {
3334 PyDict_DelItem(_PyPopenProcs,
3335 fileObj[0]);
3336 }
3337 if (!ins_rc[1] && fileObj[1])
3338 {
3339 PyDict_DelItem(_PyPopenProcs,
3340 fileObj[1]);
3341 }
3342 if (!ins_rc[2] && fileObj[2])
3343 {
3344 PyDict_DelItem(_PyPopenProcs,
3345 fileObj[2]);
3346 }
3347 }
3348 }
3349
3350 /*
3351 * Clean up our localized references for the dictionary keys
3352 * and value since PyDict_SetItem will Py_INCREF any copies
3353 * that got placed in the dictionary.
3354 */
3355 Py_XDECREF(procObj);
3356 Py_XDECREF(fileObj[0]);
3357 Py_XDECREF(fileObj[1]);
3358 Py_XDECREF(fileObj[2]);
3359 }
3360
3361 /* Child is launched. */
3362 return f;
3363}
3364
3365/*
3366 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3367 * exit code for the child process and return as a result of the close.
3368 *
3369 * This function uses the _PyPopenProcs dictionary in order to map the
3370 * input file pointer to information about the process that was
3371 * originally created by the popen* call that created the file pointer.
3372 * The dictionary uses the file pointer as a key (with one entry
3373 * inserted for each file returned by the original popen* call) and a
3374 * single list object as the value for all files from a single call.
3375 * The list object contains the Win32 process handle at [0], and a file
3376 * count at [1], which is initialized to the total number of file
3377 * handles using that list.
3378 *
3379 * This function closes whichever handle it is passed, and decrements
3380 * the file count in the dictionary for the process handle pointed to
3381 * by this file. On the last close (when the file count reaches zero),
3382 * this function will wait for the child process and then return its
3383 * exit code as the result of the close() operation. This permits the
3384 * files to be closed in any order - it is always the close() of the
3385 * final handle that will return the exit code.
3386 */
3387
3388 /* RED_FLAG 31-Aug-2000 Tim
3389 * This is always called (today!) between a pair of
3390 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3391 * macros. So the thread running this has no valid thread state, as
3392 * far as Python is concerned. However, this calls some Python API
3393 * functions that cannot be called safely without a valid thread
3394 * state, in particular PyDict_GetItem.
3395 * As a temporary hack (although it may last for years ...), we
3396 * *rely* on not having a valid thread state in this function, in
3397 * order to create our own "from scratch".
3398 * This will deadlock if _PyPclose is ever called by a thread
3399 * holding the global lock.
3400 * (The OS/2 EMX thread support appears to cover the case where the
3401 * lock is already held - AIM Apr01)
3402 */
3403
3404static int _PyPclose(FILE *file)
3405{
3406 int result;
3407 int exit_code;
3408 int pipe_pid;
3409 PyObject *procObj, *pidObj, *intObj, *fileObj;
3410 int file_count;
3411#ifdef WITH_THREAD
3412 PyInterpreterState* pInterpreterState;
3413 PyThreadState* pThreadState;
3414#endif
3415
3416 /* Close the file handle first, to ensure it can't block the
3417 * child from exiting if it's the last handle.
3418 */
3419 result = fclose(file);
3420
3421#ifdef WITH_THREAD
3422 /* Bootstrap a valid thread state into existence. */
3423 pInterpreterState = PyInterpreterState_New();
3424 if (!pInterpreterState) {
3425 /* Well, we're hosed now! We don't have a thread
3426 * state, so can't call a nice error routine, or raise
3427 * an exception. Just die.
3428 */
3429 Py_FatalError("unable to allocate interpreter state "
3430 "when closing popen object.");
3431 return -1; /* unreachable */
3432 }
3433 pThreadState = PyThreadState_New(pInterpreterState);
3434 if (!pThreadState) {
3435 Py_FatalError("unable to allocate thread state "
3436 "when closing popen object.");
3437 return -1; /* unreachable */
3438 }
3439 /* Grab the global lock. Note that this will deadlock if the
3440 * current thread already has the lock! (see RED_FLAG comments
3441 * before this function)
3442 */
3443 PyEval_RestoreThread(pThreadState);
3444#endif
3445
3446 if (_PyPopenProcs)
3447 {
3448 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3449 (procObj = PyDict_GetItem(_PyPopenProcs,
3450 fileObj)) != NULL &&
3451 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3452 (intObj = PyList_GetItem(procObj,1)) != NULL)
3453 {
3454 pipe_pid = (int) PyInt_AsLong(pidObj);
3455 file_count = (int) PyInt_AsLong(intObj);
3456
3457 if (file_count > 1)
3458 {
3459 /* Still other files referencing process */
3460 file_count--;
3461 PyList_SetItem(procObj,1,
3462 PyInt_FromLong((long) file_count));
3463 }
3464 else
3465 {
3466 /* Last file for this process */
3467 if (result != EOF &&
3468 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3469 {
3470 /* extract exit status */
3471 if (WIFEXITED(exit_code))
3472 {
3473 result = WEXITSTATUS(exit_code);
3474 }
3475 else
3476 {
3477 errno = EPIPE;
3478 result = -1;
3479 }
3480 }
3481 else
3482 {
3483 /* Indicate failure - this will cause the file object
3484 * to raise an I/O error and translate the last
3485 * error code from errno. We do have a problem with
3486 * last errors that overlap the normal errno table,
3487 * but that's a consistent problem with the file object.
3488 */
3489 result = -1;
3490 }
3491 }
3492
3493 /* Remove this file pointer from dictionary */
3494 PyDict_DelItem(_PyPopenProcs, fileObj);
3495
3496 if (PyDict_Size(_PyPopenProcs) == 0)
3497 {
3498 Py_DECREF(_PyPopenProcs);
3499 _PyPopenProcs = NULL;
3500 }
3501
3502 } /* if object retrieval ok */
3503
3504 Py_XDECREF(fileObj);
3505 } /* if _PyPopenProcs */
3506
3507#ifdef WITH_THREAD
3508 /* Tear down the thread & interpreter states.
3509 * Note that interpreter state clear & delete functions automatically
3510 * call the thread clear & delete functions, and indeed insist on
3511 * doing that themselves. The lock must be held during the clear, but
3512 * need not be held during the delete.
3513 */
3514 PyInterpreterState_Clear(pInterpreterState);
3515 PyEval_ReleaseThread(pThreadState);
3516 PyInterpreterState_Delete(pInterpreterState);
3517#endif
3518
3519 return result;
3520}
3521
3522#endif /* PYCC_??? */
3523
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003524#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003525
3526/*
3527 * Portable 'popen' replacement for Win32.
3528 *
3529 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3530 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003531 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003532 */
3533
3534#include <malloc.h>
3535#include <io.h>
3536#include <fcntl.h>
3537
3538/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3539#define POPEN_1 1
3540#define POPEN_2 2
3541#define POPEN_3 3
3542#define POPEN_4 4
3543
3544static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003545static int _PyPclose(FILE *file);
3546
3547/*
3548 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003549 * for use when retrieving the process exit code. See _PyPclose() below
3550 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003551 */
3552static PyObject *_PyPopenProcs = NULL;
3553
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003554
3555/* popen that works from a GUI.
3556 *
3557 * The result of this function is a pipe (file) connected to the
3558 * processes stdin or stdout, depending on the requested mode.
3559 */
3560
3561static PyObject *
3562posix_popen(PyObject *self, PyObject *args)
3563{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003564 PyObject *f, *s;
3565 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003566
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003567 char *cmdstring;
3568 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003569 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003570 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003571 return NULL;
3572
3573 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003574
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003575 if (*mode == 'r')
3576 tm = _O_RDONLY;
3577 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003578 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003579 return NULL;
3580 } else
3581 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003582
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003583 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003584 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003585 return NULL;
3586 }
3587
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003588 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003589 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003590 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003591 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003592 else
3593 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3594
3595 return f;
3596}
3597
3598/* Variation on win32pipe.popen
3599 *
3600 * The result of this function is a pipe (file) connected to the
3601 * process's stdin, and a pipe connected to the process's stdout.
3602 */
3603
3604static PyObject *
3605win32_popen2(PyObject *self, PyObject *args)
3606{
3607 PyObject *f;
3608 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003609
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003610 char *cmdstring;
3611 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003612 int bufsize = -1;
3613 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003614 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003615
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003616 if (*mode == 't')
3617 tm = _O_TEXT;
3618 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003619 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003620 return NULL;
3621 } else
3622 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003623
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003624 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003625 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003626 return NULL;
3627 }
3628
3629 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003630
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003631 return f;
3632}
3633
3634/*
3635 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003636 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003637 * The result of this function is 3 pipes - the process's stdin,
3638 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003639 */
3640
3641static PyObject *
3642win32_popen3(PyObject *self, PyObject *args)
3643{
3644 PyObject *f;
3645 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003646
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003647 char *cmdstring;
3648 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003649 int bufsize = -1;
3650 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003651 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003652
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003653 if (*mode == 't')
3654 tm = _O_TEXT;
3655 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003656 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003657 return NULL;
3658 } else
3659 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003660
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003661 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003662 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003663 return NULL;
3664 }
3665
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003666 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003667
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003668 return f;
3669}
3670
3671/*
3672 * Variation on win32pipe.popen
3673 *
Tim Peters5aa91602002-01-30 05:46:57 +00003674 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003675 * and stdout+stderr combined as a single pipe.
3676 */
3677
3678static PyObject *
3679win32_popen4(PyObject *self, PyObject *args)
3680{
3681 PyObject *f;
3682 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003683
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003684 char *cmdstring;
3685 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003686 int bufsize = -1;
3687 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003688 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003689
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003690 if (*mode == 't')
3691 tm = _O_TEXT;
3692 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003693 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003694 return NULL;
3695 } else
3696 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003697
3698 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003699 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003700 return NULL;
3701 }
3702
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003703 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003704
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003705 return f;
3706}
3707
Mark Hammond08501372001-01-31 07:30:29 +00003708static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003709_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003710 HANDLE hStdin,
3711 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003712 HANDLE hStderr,
3713 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003714{
3715 PROCESS_INFORMATION piProcInfo;
3716 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003717 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003718 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003719 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003720 int i;
3721 int x;
3722
3723 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003724 char *comshell;
3725
Tim Peters92e4dd82002-10-05 01:47:34 +00003726 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003727 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3728 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003729
3730 /* Explicitly check if we are using COMMAND.COM. If we are
3731 * then use the w9xpopen hack.
3732 */
3733 comshell = s1 + x;
3734 while (comshell >= s1 && *comshell != '\\')
3735 --comshell;
3736 ++comshell;
3737
3738 if (GetVersion() < 0x80000000 &&
3739 _stricmp(comshell, "command.com") != 0) {
3740 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003741 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003742 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003743 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003744 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003745 }
3746 else {
3747 /*
Tim Peters402d5982001-08-27 06:37:48 +00003748 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3749 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003750 */
Mark Hammond08501372001-01-31 07:30:29 +00003751 char modulepath[_MAX_PATH];
3752 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003753 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3754 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003755 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003756 x = i+1;
3757 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003758 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003759 strncat(modulepath,
3760 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003761 (sizeof(modulepath)/sizeof(modulepath[0]))
3762 -strlen(modulepath));
3763 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003764 /* Eeek - file-not-found - possibly an embedding
3765 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003766 */
Tim Peters5aa91602002-01-30 05:46:57 +00003767 strncpy(modulepath,
3768 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003769 sizeof(modulepath)/sizeof(modulepath[0]));
3770 if (modulepath[strlen(modulepath)-1] != '\\')
3771 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003772 strncat(modulepath,
3773 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003774 (sizeof(modulepath)/sizeof(modulepath[0]))
3775 -strlen(modulepath));
3776 /* No where else to look - raise an easily identifiable
3777 error, rather than leaving Windows to report
3778 "file not found" - as the user is probably blissfully
3779 unaware this shim EXE is used, and it will confuse them.
3780 (well, it confused me for a while ;-)
3781 */
3782 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003783 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003784 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003785 "for popen to work with your shell "
3786 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003787 szConsoleSpawn);
3788 return FALSE;
3789 }
3790 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003791 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003792 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003793 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003794
Tim Peters92e4dd82002-10-05 01:47:34 +00003795 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003796 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003797 /* To maintain correct argument passing semantics,
3798 we pass the command-line as it stands, and allow
3799 quoting to be applied. w9xpopen.exe will then
3800 use its argv vector, and re-quote the necessary
3801 args for the ultimate child process.
3802 */
Tim Peters75cdad52001-11-28 22:07:30 +00003803 PyOS_snprintf(
3804 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003805 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003806 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003807 s1,
3808 s3,
3809 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003810 /* Not passing CREATE_NEW_CONSOLE has been known to
3811 cause random failures on win9x. Specifically a
3812 dialog:
3813 "Your program accessed mem currently in use at xxx"
3814 and a hopeful warning about the stability of your
3815 system.
3816 Cost is Ctrl+C wont kill children, but anyone
3817 who cares can have a go!
3818 */
3819 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003820 }
3821 }
3822
3823 /* Could be an else here to try cmd.exe / command.com in the path
3824 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003825 else {
Tim Peters402d5982001-08-27 06:37:48 +00003826 PyErr_SetString(PyExc_RuntimeError,
3827 "Cannot locate a COMSPEC environment variable to "
3828 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003829 return FALSE;
3830 }
Tim Peters5aa91602002-01-30 05:46:57 +00003831
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003832 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3833 siStartInfo.cb = sizeof(STARTUPINFO);
3834 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3835 siStartInfo.hStdInput = hStdin;
3836 siStartInfo.hStdOutput = hStdout;
3837 siStartInfo.hStdError = hStderr;
3838 siStartInfo.wShowWindow = SW_HIDE;
3839
3840 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003841 s2,
3842 NULL,
3843 NULL,
3844 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003845 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003846 NULL,
3847 NULL,
3848 &siStartInfo,
3849 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003850 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003851 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003852
Mark Hammondb37a3732000-08-14 04:47:33 +00003853 /* Return process handle */
3854 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003855 return TRUE;
3856 }
Tim Peters402d5982001-08-27 06:37:48 +00003857 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003858 return FALSE;
3859}
3860
3861/* The following code is based off of KB: Q190351 */
3862
3863static PyObject *
3864_PyPopen(char *cmdstring, int mode, int n)
3865{
3866 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
3867 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00003868 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00003869
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003870 SECURITY_ATTRIBUTES saAttr;
3871 BOOL fSuccess;
3872 int fd1, fd2, fd3;
3873 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00003874 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003875 PyObject *f;
3876
3877 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
3878 saAttr.bInheritHandle = TRUE;
3879 saAttr.lpSecurityDescriptor = NULL;
3880
3881 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
3882 return win32_error("CreatePipe", NULL);
3883
3884 /* Create new output read handle and the input write handle. Set
3885 * the inheritance properties to FALSE. Otherwise, the child inherits
3886 * the these handles; resulting in non-closeable handles to the pipes
3887 * being created. */
3888 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003889 GetCurrentProcess(), &hChildStdinWrDup, 0,
3890 FALSE,
3891 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003892 if (!fSuccess)
3893 return win32_error("DuplicateHandle", NULL);
3894
3895 /* Close the inheritable version of ChildStdin
3896 that we're using. */
3897 CloseHandle(hChildStdinWr);
3898
3899 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
3900 return win32_error("CreatePipe", NULL);
3901
3902 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003903 GetCurrentProcess(), &hChildStdoutRdDup, 0,
3904 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003905 if (!fSuccess)
3906 return win32_error("DuplicateHandle", NULL);
3907
3908 /* Close the inheritable version of ChildStdout
3909 that we're using. */
3910 CloseHandle(hChildStdoutRd);
3911
3912 if (n != POPEN_4) {
3913 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
3914 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003915 fSuccess = DuplicateHandle(GetCurrentProcess(),
3916 hChildStderrRd,
3917 GetCurrentProcess(),
3918 &hChildStderrRdDup, 0,
3919 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003920 if (!fSuccess)
3921 return win32_error("DuplicateHandle", NULL);
3922 /* Close the inheritable version of ChildStdErr that we're using. */
3923 CloseHandle(hChildStderrRd);
3924 }
Tim Peters5aa91602002-01-30 05:46:57 +00003925
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003926 switch (n) {
3927 case POPEN_1:
3928 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
3929 case _O_WRONLY | _O_TEXT:
3930 /* Case for writing to child Stdin in text mode. */
3931 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3932 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003933 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003934 PyFile_SetBufSize(f, 0);
3935 /* We don't care about these pipes anymore, so close them. */
3936 CloseHandle(hChildStdoutRdDup);
3937 CloseHandle(hChildStderrRdDup);
3938 break;
3939
3940 case _O_RDONLY | _O_TEXT:
3941 /* Case for reading from child Stdout in text mode. */
3942 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3943 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003944 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003945 PyFile_SetBufSize(f, 0);
3946 /* We don't care about these pipes anymore, so close them. */
3947 CloseHandle(hChildStdinWrDup);
3948 CloseHandle(hChildStderrRdDup);
3949 break;
3950
3951 case _O_RDONLY | _O_BINARY:
3952 /* Case for readinig from child Stdout in binary mode. */
3953 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3954 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003955 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003956 PyFile_SetBufSize(f, 0);
3957 /* We don't care about these pipes anymore, so close them. */
3958 CloseHandle(hChildStdinWrDup);
3959 CloseHandle(hChildStderrRdDup);
3960 break;
3961
3962 case _O_WRONLY | _O_BINARY:
3963 /* Case for writing to child Stdin in binary mode. */
3964 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3965 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00003966 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003967 PyFile_SetBufSize(f, 0);
3968 /* We don't care about these pipes anymore, so close them. */
3969 CloseHandle(hChildStdoutRdDup);
3970 CloseHandle(hChildStderrRdDup);
3971 break;
3972 }
Mark Hammondb37a3732000-08-14 04:47:33 +00003973 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003974 break;
Tim Peters5aa91602002-01-30 05:46:57 +00003975
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003976 case POPEN_2:
3977 case POPEN_4:
3978 {
3979 char *m1, *m2;
3980 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00003981
Tim Peters7dca21e2002-08-19 00:42:29 +00003982 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003983 m1 = "r";
3984 m2 = "w";
3985 } else {
3986 m1 = "rb";
3987 m2 = "wb";
3988 }
3989
3990 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
3991 f1 = _fdopen(fd1, m2);
3992 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
3993 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003994 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003995 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00003996 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003997 PyFile_SetBufSize(p2, 0);
3998
3999 if (n != 4)
4000 CloseHandle(hChildStderrRdDup);
4001
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004002 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004003 Py_XDECREF(p1);
4004 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004005 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004006 break;
4007 }
Tim Peters5aa91602002-01-30 05:46:57 +00004008
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004009 case POPEN_3:
4010 {
4011 char *m1, *m2;
4012 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004013
Tim Peters7dca21e2002-08-19 00:42:29 +00004014 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004015 m1 = "r";
4016 m2 = "w";
4017 } else {
4018 m1 = "rb";
4019 m2 = "wb";
4020 }
4021
4022 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4023 f1 = _fdopen(fd1, m2);
4024 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4025 f2 = _fdopen(fd2, m1);
4026 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4027 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004028 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004029 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4030 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004031 PyFile_SetBufSize(p1, 0);
4032 PyFile_SetBufSize(p2, 0);
4033 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004034 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004035 Py_XDECREF(p1);
4036 Py_XDECREF(p2);
4037 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004038 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004039 break;
4040 }
4041 }
4042
4043 if (n == POPEN_4) {
4044 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004045 hChildStdinRd,
4046 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004047 hChildStdoutWr,
4048 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004049 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004050 }
4051 else {
4052 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004053 hChildStdinRd,
4054 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004055 hChildStderrWr,
4056 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004057 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004058 }
4059
Mark Hammondb37a3732000-08-14 04:47:33 +00004060 /*
4061 * Insert the files we've created into the process dictionary
4062 * all referencing the list with the process handle and the
4063 * initial number of files (see description below in _PyPclose).
4064 * Since if _PyPclose later tried to wait on a process when all
4065 * handles weren't closed, it could create a deadlock with the
4066 * child, we spend some energy here to try to ensure that we
4067 * either insert all file handles into the dictionary or none
4068 * at all. It's a little clumsy with the various popen modes
4069 * and variable number of files involved.
4070 */
4071 if (!_PyPopenProcs) {
4072 _PyPopenProcs = PyDict_New();
4073 }
4074
4075 if (_PyPopenProcs) {
4076 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4077 int ins_rc[3];
4078
4079 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4080 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4081
4082 procObj = PyList_New(2);
4083 hProcessObj = PyLong_FromVoidPtr(hProcess);
4084 intObj = PyInt_FromLong(file_count);
4085
4086 if (procObj && hProcessObj && intObj) {
4087 PyList_SetItem(procObj,0,hProcessObj);
4088 PyList_SetItem(procObj,1,intObj);
4089
4090 fileObj[0] = PyLong_FromVoidPtr(f1);
4091 if (fileObj[0]) {
4092 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4093 fileObj[0],
4094 procObj);
4095 }
4096 if (file_count >= 2) {
4097 fileObj[1] = PyLong_FromVoidPtr(f2);
4098 if (fileObj[1]) {
4099 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4100 fileObj[1],
4101 procObj);
4102 }
4103 }
4104 if (file_count >= 3) {
4105 fileObj[2] = PyLong_FromVoidPtr(f3);
4106 if (fileObj[2]) {
4107 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4108 fileObj[2],
4109 procObj);
4110 }
4111 }
4112
4113 if (ins_rc[0] < 0 || !fileObj[0] ||
4114 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4115 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4116 /* Something failed - remove any dictionary
4117 * entries that did make it.
4118 */
4119 if (!ins_rc[0] && fileObj[0]) {
4120 PyDict_DelItem(_PyPopenProcs,
4121 fileObj[0]);
4122 }
4123 if (!ins_rc[1] && fileObj[1]) {
4124 PyDict_DelItem(_PyPopenProcs,
4125 fileObj[1]);
4126 }
4127 if (!ins_rc[2] && fileObj[2]) {
4128 PyDict_DelItem(_PyPopenProcs,
4129 fileObj[2]);
4130 }
4131 }
4132 }
Tim Peters5aa91602002-01-30 05:46:57 +00004133
Mark Hammondb37a3732000-08-14 04:47:33 +00004134 /*
4135 * Clean up our localized references for the dictionary keys
4136 * and value since PyDict_SetItem will Py_INCREF any copies
4137 * that got placed in the dictionary.
4138 */
4139 Py_XDECREF(procObj);
4140 Py_XDECREF(fileObj[0]);
4141 Py_XDECREF(fileObj[1]);
4142 Py_XDECREF(fileObj[2]);
4143 }
4144
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004145 /* Child is launched. Close the parents copy of those pipe
4146 * handles that only the child should have open. You need to
4147 * make sure that no handles to the write end of the output pipe
4148 * are maintained in this process or else the pipe will not close
4149 * when the child process exits and the ReadFile will hang. */
4150
4151 if (!CloseHandle(hChildStdinRd))
4152 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004153
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004154 if (!CloseHandle(hChildStdoutWr))
4155 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004156
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004157 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4158 return win32_error("CloseHandle", NULL);
4159
4160 return f;
4161}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004162
4163/*
4164 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4165 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004166 *
4167 * This function uses the _PyPopenProcs dictionary in order to map the
4168 * input file pointer to information about the process that was
4169 * originally created by the popen* call that created the file pointer.
4170 * The dictionary uses the file pointer as a key (with one entry
4171 * inserted for each file returned by the original popen* call) and a
4172 * single list object as the value for all files from a single call.
4173 * The list object contains the Win32 process handle at [0], and a file
4174 * count at [1], which is initialized to the total number of file
4175 * handles using that list.
4176 *
4177 * This function closes whichever handle it is passed, and decrements
4178 * the file count in the dictionary for the process handle pointed to
4179 * by this file. On the last close (when the file count reaches zero),
4180 * this function will wait for the child process and then return its
4181 * exit code as the result of the close() operation. This permits the
4182 * files to be closed in any order - it is always the close() of the
4183 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004184 */
Tim Peters736aa322000-09-01 06:51:24 +00004185
4186 /* RED_FLAG 31-Aug-2000 Tim
4187 * This is always called (today!) between a pair of
4188 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4189 * macros. So the thread running this has no valid thread state, as
4190 * far as Python is concerned. However, this calls some Python API
4191 * functions that cannot be called safely without a valid thread
4192 * state, in particular PyDict_GetItem.
4193 * As a temporary hack (although it may last for years ...), we
4194 * *rely* on not having a valid thread state in this function, in
4195 * order to create our own "from scratch".
4196 * This will deadlock if _PyPclose is ever called by a thread
4197 * holding the global lock.
4198 */
4199
Fredrik Lundh56055a42000-07-23 19:47:12 +00004200static int _PyPclose(FILE *file)
4201{
Fredrik Lundh20318932000-07-26 17:29:12 +00004202 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004203 DWORD exit_code;
4204 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004205 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4206 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004207#ifdef WITH_THREAD
4208 PyInterpreterState* pInterpreterState;
4209 PyThreadState* pThreadState;
4210#endif
4211
Fredrik Lundh20318932000-07-26 17:29:12 +00004212 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004213 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004214 */
4215 result = fclose(file);
4216
Tim Peters736aa322000-09-01 06:51:24 +00004217#ifdef WITH_THREAD
4218 /* Bootstrap a valid thread state into existence. */
4219 pInterpreterState = PyInterpreterState_New();
4220 if (!pInterpreterState) {
4221 /* Well, we're hosed now! We don't have a thread
4222 * state, so can't call a nice error routine, or raise
4223 * an exception. Just die.
4224 */
4225 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004226 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004227 return -1; /* unreachable */
4228 }
4229 pThreadState = PyThreadState_New(pInterpreterState);
4230 if (!pThreadState) {
4231 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004232 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004233 return -1; /* unreachable */
4234 }
4235 /* Grab the global lock. Note that this will deadlock if the
4236 * current thread already has the lock! (see RED_FLAG comments
4237 * before this function)
4238 */
4239 PyEval_RestoreThread(pThreadState);
4240#endif
4241
Fredrik Lundh56055a42000-07-23 19:47:12 +00004242 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004243 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4244 (procObj = PyDict_GetItem(_PyPopenProcs,
4245 fileObj)) != NULL &&
4246 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4247 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4248
4249 hProcess = PyLong_AsVoidPtr(hProcessObj);
4250 file_count = PyInt_AsLong(intObj);
4251
4252 if (file_count > 1) {
4253 /* Still other files referencing process */
4254 file_count--;
4255 PyList_SetItem(procObj,1,
4256 PyInt_FromLong(file_count));
4257 } else {
4258 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004259 if (result != EOF &&
4260 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4261 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004262 /* Possible truncation here in 16-bit environments, but
4263 * real exit codes are just the lower byte in any event.
4264 */
4265 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004266 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004267 /* Indicate failure - this will cause the file object
4268 * to raise an I/O error and translate the last Win32
4269 * error code from errno. We do have a problem with
4270 * last errors that overlap the normal errno table,
4271 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004272 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004273 if (result != EOF) {
4274 /* If the error wasn't from the fclose(), then
4275 * set errno for the file object error handling.
4276 */
4277 errno = GetLastError();
4278 }
4279 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004280 }
4281
4282 /* Free up the native handle at this point */
4283 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004284 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004285
Mark Hammondb37a3732000-08-14 04:47:33 +00004286 /* Remove this file pointer from dictionary */
4287 PyDict_DelItem(_PyPopenProcs, fileObj);
4288
4289 if (PyDict_Size(_PyPopenProcs) == 0) {
4290 Py_DECREF(_PyPopenProcs);
4291 _PyPopenProcs = NULL;
4292 }
4293
4294 } /* if object retrieval ok */
4295
4296 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004297 } /* if _PyPopenProcs */
4298
Tim Peters736aa322000-09-01 06:51:24 +00004299#ifdef WITH_THREAD
4300 /* Tear down the thread & interpreter states.
4301 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004302 * call the thread clear & delete functions, and indeed insist on
4303 * doing that themselves. The lock must be held during the clear, but
4304 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004305 */
4306 PyInterpreterState_Clear(pInterpreterState);
4307 PyEval_ReleaseThread(pThreadState);
4308 PyInterpreterState_Delete(pInterpreterState);
4309#endif
4310
Fredrik Lundh56055a42000-07-23 19:47:12 +00004311 return result;
4312}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004313
4314#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004315static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004316posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004317{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004318 char *name;
4319 char *mode = "r";
4320 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004321 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004322 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004323 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004324 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004325 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004326 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004327 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004328 if (fp == NULL)
4329 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004330 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004331 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004332 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004333 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004334}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004335
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004336#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004337#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004338
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004339
Guido van Rossumb6775db1994-08-01 11:34:53 +00004340#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004341PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004342"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004343Set the current process's user id.");
4344
Barry Warsaw53699e91996-12-10 23:23:01 +00004345static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004346posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004347{
4348 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004349 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004350 return NULL;
4351 if (setuid(uid) < 0)
4352 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004353 Py_INCREF(Py_None);
4354 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004355}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004356#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004357
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004358
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004359#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004360PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004361"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004362Set the current process's effective user id.");
4363
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004364static PyObject *
4365posix_seteuid (PyObject *self, PyObject *args)
4366{
4367 int euid;
4368 if (!PyArg_ParseTuple(args, "i", &euid)) {
4369 return NULL;
4370 } else if (seteuid(euid) < 0) {
4371 return posix_error();
4372 } else {
4373 Py_INCREF(Py_None);
4374 return Py_None;
4375 }
4376}
4377#endif /* HAVE_SETEUID */
4378
4379#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004380PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004381"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004382Set the current process's effective group id.");
4383
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004384static PyObject *
4385posix_setegid (PyObject *self, PyObject *args)
4386{
4387 int egid;
4388 if (!PyArg_ParseTuple(args, "i", &egid)) {
4389 return NULL;
4390 } else if (setegid(egid) < 0) {
4391 return posix_error();
4392 } else {
4393 Py_INCREF(Py_None);
4394 return Py_None;
4395 }
4396}
4397#endif /* HAVE_SETEGID */
4398
4399#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004400PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004401"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004402Set the current process's real and effective user ids.");
4403
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004404static PyObject *
4405posix_setreuid (PyObject *self, PyObject *args)
4406{
4407 int ruid, euid;
4408 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4409 return NULL;
4410 } else if (setreuid(ruid, euid) < 0) {
4411 return posix_error();
4412 } else {
4413 Py_INCREF(Py_None);
4414 return Py_None;
4415 }
4416}
4417#endif /* HAVE_SETREUID */
4418
4419#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004420PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004421"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004422Set the current process's real and effective group ids.");
4423
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004424static PyObject *
4425posix_setregid (PyObject *self, PyObject *args)
4426{
4427 int rgid, egid;
4428 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4429 return NULL;
4430 } else if (setregid(rgid, egid) < 0) {
4431 return posix_error();
4432 } else {
4433 Py_INCREF(Py_None);
4434 return Py_None;
4435 }
4436}
4437#endif /* HAVE_SETREGID */
4438
Guido van Rossumb6775db1994-08-01 11:34:53 +00004439#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004440PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004441"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004442Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004443
Barry Warsaw53699e91996-12-10 23:23:01 +00004444static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004445posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004446{
4447 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004448 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004449 return NULL;
4450 if (setgid(gid) < 0)
4451 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004452 Py_INCREF(Py_None);
4453 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004454}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004455#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004456
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004457#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004458PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004459"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004460Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004461
4462static PyObject *
4463posix_setgroups(PyObject *self, PyObject *args)
4464{
4465 PyObject *groups;
4466 int i, len;
4467 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004468
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004469 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4470 return NULL;
4471 if (!PySequence_Check(groups)) {
4472 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4473 return NULL;
4474 }
4475 len = PySequence_Size(groups);
4476 if (len > MAX_GROUPS) {
4477 PyErr_SetString(PyExc_ValueError, "too many groups");
4478 return NULL;
4479 }
4480 for(i = 0; i < len; i++) {
4481 PyObject *elem;
4482 elem = PySequence_GetItem(groups, i);
4483 if (!elem)
4484 return NULL;
4485 if (!PyInt_Check(elem)) {
4486 PyErr_SetString(PyExc_TypeError,
4487 "groups must be integers");
4488 Py_DECREF(elem);
4489 return NULL;
4490 }
4491 /* XXX: check that value fits into gid_t. */
4492 grouplist[i] = PyInt_AsLong(elem);
4493 Py_DECREF(elem);
4494 }
4495
4496 if (setgroups(len, grouplist) < 0)
4497 return posix_error();
4498 Py_INCREF(Py_None);
4499 return Py_None;
4500}
4501#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004502
Guido van Rossumb6775db1994-08-01 11:34:53 +00004503#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004504PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004505"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004506Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004507
Barry Warsaw53699e91996-12-10 23:23:01 +00004508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004509posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004510{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004511 int pid, options;
4512#ifdef UNION_WAIT
4513 union wait status;
4514#define status_i (status.w_status)
4515#else
4516 int status;
4517#define status_i status
4518#endif
4519 status_i = 0;
4520
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004521 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004522 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004523 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004524 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004525 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004526 if (pid == -1)
4527 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004528 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004529 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004530}
4531
Tim Petersab034fa2002-02-01 11:27:43 +00004532#elif defined(HAVE_CWAIT)
4533
4534/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004535PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004536"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004537"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004538
4539static PyObject *
4540posix_waitpid(PyObject *self, PyObject *args)
4541{
4542 int pid, options;
4543 int status;
4544
4545 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4546 return NULL;
4547 Py_BEGIN_ALLOW_THREADS
4548 pid = _cwait(&status, pid, options);
4549 Py_END_ALLOW_THREADS
4550 if (pid == -1)
4551 return posix_error();
4552 else
4553 /* shift the status left a byte so this is more like the
4554 POSIX waitpid */
4555 return Py_BuildValue("ii", pid, status << 8);
4556}
4557#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004558
Guido van Rossumad0ee831995-03-01 10:34:45 +00004559#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004560PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004561"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004562Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004563
Barry Warsaw53699e91996-12-10 23:23:01 +00004564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004565posix_wait(PyObject *self, PyObject *args)
Guido van Rossum21803b81992-08-09 12:55:27 +00004566{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004567 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004568#ifdef UNION_WAIT
4569 union wait status;
4570#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004571#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004572 int status;
4573#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004574#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004575 if (!PyArg_ParseTuple(args, ":wait"))
4576 return NULL;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004577 status_i = 0;
4578 Py_BEGIN_ALLOW_THREADS
4579 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004580 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004581 if (pid == -1)
4582 return posix_error();
4583 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004584 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004585#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004586}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004587#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004588
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004589
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004590PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004591"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004592Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004593
Barry Warsaw53699e91996-12-10 23:23:01 +00004594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004595posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004596{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004597#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004598 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004599#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004600#ifdef MS_WINDOWS
4601 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4602#else
4603 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4604#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004605#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004606}
4607
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004608
Guido van Rossumb6775db1994-08-01 11:34:53 +00004609#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004610PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004611"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004612Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004613
Barry Warsaw53699e91996-12-10 23:23:01 +00004614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004615posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004616{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004617 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004618 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004619 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004620 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004621 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004622 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004623 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004624 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004625 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004626 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004627 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004628}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004629#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004631
Guido van Rossumb6775db1994-08-01 11:34:53 +00004632#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004633PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004634"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004635Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004636
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004638posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004639{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004640 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004641}
4642#endif /* HAVE_SYMLINK */
4643
4644
4645#ifdef HAVE_TIMES
4646#ifndef HZ
4647#define HZ 60 /* Universal constant :-) */
4648#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004649
Guido van Rossumd48f2521997-12-05 22:19:34 +00004650#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4651static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004652system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004653{
4654 ULONG value = 0;
4655
4656 Py_BEGIN_ALLOW_THREADS
4657 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4658 Py_END_ALLOW_THREADS
4659
4660 return value;
4661}
4662
4663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004664posix_times(PyObject *self, PyObject *args)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004665{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004666 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossumd48f2521997-12-05 22:19:34 +00004667 return NULL;
4668
4669 /* Currently Only Uptime is Provided -- Others Later */
4670 return Py_BuildValue("ddddd",
4671 (double)0 /* t.tms_utime / HZ */,
4672 (double)0 /* t.tms_stime / HZ */,
4673 (double)0 /* t.tms_cutime / HZ */,
4674 (double)0 /* t.tms_cstime / HZ */,
4675 (double)system_uptime() / 1000);
4676}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004677#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004679posix_times(PyObject *self, PyObject *args)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004680{
4681 struct tms t;
4682 clock_t c;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004683 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum22db57e1992-04-05 14:25:30 +00004684 return NULL;
4685 errno = 0;
4686 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004687 if (c == (clock_t) -1)
4688 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004689 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004690 (double)t.tms_utime / HZ,
4691 (double)t.tms_stime / HZ,
4692 (double)t.tms_cutime / HZ,
4693 (double)t.tms_cstime / HZ,
4694 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004695}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004696#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004697#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004698
4699
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004700#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004701#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004703posix_times(PyObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004704{
4705 FILETIME create, exit, kernel, user;
4706 HANDLE hProc;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004707 if (!PyArg_ParseTuple(args, ":times"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004708 return NULL;
4709 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004710 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4711 /* The fields of a FILETIME structure are the hi and lo part
4712 of a 64-bit value expressed in 100 nanosecond units.
4713 1e7 is one second in such units; 1e-7 the inverse.
4714 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4715 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004716 return Py_BuildValue(
4717 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004718 (double)(kernel.dwHighDateTime*429.4967296 +
4719 kernel.dwLowDateTime*1e-7),
4720 (double)(user.dwHighDateTime*429.4967296 +
4721 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004722 (double)0,
4723 (double)0,
4724 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004725}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004726#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004727
4728#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004729PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004730"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004731Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004732#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004733
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004734
Guido van Rossumb6775db1994-08-01 11:34:53 +00004735#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004736PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004737"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004738Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004739
Barry Warsaw53699e91996-12-10 23:23:01 +00004740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004741posix_setsid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004742{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004743 if (!PyArg_ParseTuple(args, ":setsid"))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004744 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004745 if (setsid() < 0)
4746 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004747 Py_INCREF(Py_None);
4748 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004749}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004750#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004751
Guido van Rossumb6775db1994-08-01 11:34:53 +00004752#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004753PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004754"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004755Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004756
Barry Warsaw53699e91996-12-10 23:23:01 +00004757static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004758posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004759{
4760 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004761 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004762 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004763 if (setpgid(pid, pgrp) < 0)
4764 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004765 Py_INCREF(Py_None);
4766 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004767}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004768#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004769
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004770
Guido van Rossumb6775db1994-08-01 11:34:53 +00004771#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004772PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004773"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004774Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004775
Barry Warsaw53699e91996-12-10 23:23:01 +00004776static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004777posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004778{
4779 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004780 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004781 return NULL;
4782 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004783 if (pgid < 0)
4784 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004785 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004786}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004787#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004788
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004789
Guido van Rossumb6775db1994-08-01 11:34:53 +00004790#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004791PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004792"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004793Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004794
Barry Warsaw53699e91996-12-10 23:23:01 +00004795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004796posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004797{
4798 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004799 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004800 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004801 if (tcsetpgrp(fd, pgid) < 0)
4802 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004803 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004804 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004805}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004806#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004807
Guido van Rossum687dd131993-05-17 08:34:16 +00004808/* Functions acting on file descriptors */
4809
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004810PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004811"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004812Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004813
Barry Warsaw53699e91996-12-10 23:23:01 +00004814static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004815posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004816{
Mark Hammondef8b6542001-05-13 08:04:26 +00004817 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004818 int flag;
4819 int mode = 0777;
4820 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004821
4822#ifdef MS_WINDOWS
4823 if (unicode_file_names()) {
4824 PyUnicodeObject *po;
4825 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4826 Py_BEGIN_ALLOW_THREADS
4827 /* PyUnicode_AS_UNICODE OK without thread
4828 lock as it is a simple dereference. */
4829 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4830 Py_END_ALLOW_THREADS
4831 if (fd < 0)
4832 return posix_error();
4833 return PyInt_FromLong((long)fd);
4834 }
4835 /* Drop the argument parsing error as narrow strings
4836 are also valid. */
4837 PyErr_Clear();
4838 }
4839#endif
4840
Tim Peters5aa91602002-01-30 05:46:57 +00004841 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004842 Py_FileSystemDefaultEncoding, &file,
4843 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004844 return NULL;
4845
Barry Warsaw53699e91996-12-10 23:23:01 +00004846 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004847 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004848 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004849 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00004850 return posix_error_with_allocated_filename(file);
4851 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00004852 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004853}
4854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004855
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004856PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004857"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004858Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004859
Barry Warsaw53699e91996-12-10 23:23:01 +00004860static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004861posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004862{
4863 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004864 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004865 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004866 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004867 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004868 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004869 if (res < 0)
4870 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004871 Py_INCREF(Py_None);
4872 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004873}
4874
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004875
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004876PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004877"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004878Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004879
Barry Warsaw53699e91996-12-10 23:23:01 +00004880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004881posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004882{
4883 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004884 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00004885 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004886 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004887 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00004888 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004889 if (fd < 0)
4890 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004891 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004892}
4893
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004894
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004895PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004896"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004897Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004898
Barry Warsaw53699e91996-12-10 23:23:01 +00004899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004900posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004901{
4902 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004903 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00004904 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004905 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004906 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00004907 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004908 if (res < 0)
4909 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004910 Py_INCREF(Py_None);
4911 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00004912}
4913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004914
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004915PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004916"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004917Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004918
Barry Warsaw53699e91996-12-10 23:23:01 +00004919static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004920posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004921{
4922 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004923#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004924 LONG_LONG pos, res;
4925#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00004926 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00004927#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00004928 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004929 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00004930 return NULL;
4931#ifdef SEEK_SET
4932 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
4933 switch (how) {
4934 case 0: how = SEEK_SET; break;
4935 case 1: how = SEEK_CUR; break;
4936 case 2: how = SEEK_END; break;
4937 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004938#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00004939
4940#if !defined(HAVE_LARGEFILE_SUPPORT)
4941 pos = PyInt_AsLong(posobj);
4942#else
4943 pos = PyLong_Check(posobj) ?
4944 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
4945#endif
4946 if (PyErr_Occurred())
4947 return NULL;
4948
Barry Warsaw53699e91996-12-10 23:23:01 +00004949 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004950#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00004951 res = _lseeki64(fd, pos, how);
4952#else
Guido van Rossum687dd131993-05-17 08:34:16 +00004953 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00004954#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00004955 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00004956 if (res < 0)
4957 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00004958
4959#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00004960 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00004961#else
4962 return PyLong_FromLongLong(res);
4963#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00004964}
4965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004966
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004967PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004968"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004969Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970
Barry Warsaw53699e91996-12-10 23:23:01 +00004971static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004972posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004973{
Guido van Rossum8bac5461996-06-11 18:38:48 +00004974 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00004975 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004976 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00004977 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004978 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00004979 if (buffer == NULL)
4980 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004981 Py_BEGIN_ALLOW_THREADS
4982 n = read(fd, PyString_AsString(buffer), size);
4983 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00004984 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00004985 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00004986 return posix_error();
4987 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00004988 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00004989 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00004990 return buffer;
4991}
4992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004993
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004995"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004996Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004997
Barry Warsaw53699e91996-12-10 23:23:01 +00004998static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004999posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005000{
5001 int fd, size;
5002 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005003 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005004 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005005 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005006 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005007 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005008 if (size < 0)
5009 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005010 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005011}
5012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005013
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005015"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005016Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005017
Barry Warsaw53699e91996-12-10 23:23:01 +00005018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005019posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005020{
5021 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005022 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005023 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005024 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005025 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005026 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005027 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005028 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005029 if (res != 0)
5030 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005031
Fred Drake699f3522000-06-29 21:12:41 +00005032 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005033}
5034
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005035
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005036PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005037"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005038Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005039
Barry Warsaw53699e91996-12-10 23:23:01 +00005040static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005041posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005042{
Guido van Rossum687dd131993-05-17 08:34:16 +00005043 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005044 char *mode = "r";
5045 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005046 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005047 PyObject *f;
5048 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005049 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005050
Thomas Heller1f043e22002-11-07 16:00:59 +00005051 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5052 PyErr_Format(PyExc_ValueError,
5053 "invalid file mode '%s'", mode);
5054 return NULL;
5055 }
5056
Barry Warsaw53699e91996-12-10 23:23:01 +00005057 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005058 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005059 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005060 if (fp == NULL)
5061 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005062 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005063 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005064 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005065 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005066}
5067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005068PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005069"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005070Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005071connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005072
5073static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005074posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005075{
5076 int fd;
5077 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5078 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005079 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005080}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005081
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005082#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005083PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005084"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005085Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005086
Barry Warsaw53699e91996-12-10 23:23:01 +00005087static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005088posix_pipe(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005089{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005090#if defined(PYOS_OS2)
5091 HFILE read, write;
5092 APIRET rc;
5093
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005094 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005095 return NULL;
5096
5097 Py_BEGIN_ALLOW_THREADS
5098 rc = DosCreatePipe( &read, &write, 4096);
5099 Py_END_ALLOW_THREADS
5100 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005101 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005102
5103 return Py_BuildValue("(ii)", read, write);
5104#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005105#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005106 int fds[2];
5107 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005108 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum687dd131993-05-17 08:34:16 +00005109 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005110 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005111 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005112 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005113 if (res != 0)
5114 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005115 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005116#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005117 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005118 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005119 BOOL ok;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005120 if (!PyArg_ParseTuple(args, ":pipe"))
Guido van Rossum794d8131994-08-23 13:48:48 +00005121 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005122 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005123 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005124 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005125 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005126 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005127 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5128 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005129 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005130#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005131#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005132}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005133#endif /* HAVE_PIPE */
5134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005135
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005136#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005137PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005138"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005139Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005140
Barry Warsaw53699e91996-12-10 23:23:01 +00005141static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005142posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005143{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005144 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005145 int mode = 0666;
5146 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005147 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005148 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005149 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005150 res = mkfifo(filename, mode);
5151 Py_END_ALLOW_THREADS
5152 if (res < 0)
5153 return posix_error();
5154 Py_INCREF(Py_None);
5155 return Py_None;
5156}
5157#endif
5158
5159
Neal Norwitz11690112002-07-30 01:08:28 +00005160#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005161PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005162"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005163Create a filesystem node (file, device special file or named pipe)\n\
5164named filename. mode specifies both the permissions to use and the\n\
5165type of node to be created, being combined (bitwise OR) with one of\n\
5166S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005167device defines the newly created device special file (probably using\n\
5168os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005169
5170
5171static PyObject *
5172posix_mknod(PyObject *self, PyObject *args)
5173{
5174 char *filename;
5175 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005176 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005177 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005178 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005179 return NULL;
5180 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005181 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005182 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005183 if (res < 0)
5184 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005185 Py_INCREF(Py_None);
5186 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005187}
5188#endif
5189
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005190#ifdef HAVE_DEVICE_MACROS
5191PyDoc_STRVAR(posix_major__doc__,
5192"major(device) -> major number\n\
5193Extracts a device major number from a raw device number.");
5194
5195static PyObject *
5196posix_major(PyObject *self, PyObject *args)
5197{
5198 int device;
5199 if (!PyArg_ParseTuple(args, "i:major", &device))
5200 return NULL;
5201 return PyInt_FromLong((long)major(device));
5202}
5203
5204PyDoc_STRVAR(posix_minor__doc__,
5205"minor(device) -> minor number\n\
5206Extracts a device minor number from a raw device number.");
5207
5208static PyObject *
5209posix_minor(PyObject *self, PyObject *args)
5210{
5211 int device;
5212 if (!PyArg_ParseTuple(args, "i:minor", &device))
5213 return NULL;
5214 return PyInt_FromLong((long)minor(device));
5215}
5216
5217PyDoc_STRVAR(posix_makedev__doc__,
5218"makedev(major, minor) -> device number\n\
5219Composes a raw device number from the major and minor device numbers.");
5220
5221static PyObject *
5222posix_makedev(PyObject *self, PyObject *args)
5223{
5224 int major, minor;
5225 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5226 return NULL;
5227 return PyInt_FromLong((long)makedev(major, minor));
5228}
5229#endif /* device macros */
5230
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005231
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005232#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005233PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005234"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005235Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005236
Barry Warsaw53699e91996-12-10 23:23:01 +00005237static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005238posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005239{
5240 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005241 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005242 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005243 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005244
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005245 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005246 return NULL;
5247
5248#if !defined(HAVE_LARGEFILE_SUPPORT)
5249 length = PyInt_AsLong(lenobj);
5250#else
5251 length = PyLong_Check(lenobj) ?
5252 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5253#endif
5254 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005255 return NULL;
5256
Barry Warsaw53699e91996-12-10 23:23:01 +00005257 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005258 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005259 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005260 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005261 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005262 return NULL;
5263 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005264 Py_INCREF(Py_None);
5265 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005266}
5267#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005268
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005269#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005270PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005271"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005272Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005273
Fred Drake762e2061999-08-26 17:23:54 +00005274/* Save putenv() parameters as values here, so we can collect them when they
5275 * get re-set with another call for the same key. */
5276static PyObject *posix_putenv_garbage;
5277
Tim Peters5aa91602002-01-30 05:46:57 +00005278static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005279posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005280{
5281 char *s1, *s2;
5282 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005283 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005284 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005285
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005286 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005287 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005288
5289#if defined(PYOS_OS2)
5290 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5291 APIRET rc;
5292
5293 if (strlen(s2) == 0) /* If New Value is an Empty String */
5294 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5295
5296 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5297 if (rc != NO_ERROR)
5298 return os2_error(rc);
5299
5300 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5301 APIRET rc;
5302
5303 if (strlen(s2) == 0) /* If New Value is an Empty String */
5304 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5305
5306 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5307 if (rc != NO_ERROR)
5308 return os2_error(rc);
5309 } else {
5310#endif
5311
Fred Drake762e2061999-08-26 17:23:54 +00005312 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005313 len = strlen(s1) + strlen(s2) + 2;
5314 /* len includes space for a trailing \0; the size arg to
5315 PyString_FromStringAndSize does not count that */
5316 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005317 if (newstr == NULL)
5318 return PyErr_NoMemory();
5319 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005320 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005321 if (putenv(new)) {
5322 posix_error();
5323 return NULL;
5324 }
Fred Drake762e2061999-08-26 17:23:54 +00005325 /* Install the first arg and newstr in posix_putenv_garbage;
5326 * this will cause previous value to be collected. This has to
5327 * happen after the real putenv() call because the old value
5328 * was still accessible until then. */
5329 if (PyDict_SetItem(posix_putenv_garbage,
5330 PyTuple_GET_ITEM(args, 0), newstr)) {
5331 /* really not much we can do; just leak */
5332 PyErr_Clear();
5333 }
5334 else {
5335 Py_DECREF(newstr);
5336 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005337
5338#if defined(PYOS_OS2)
5339 }
5340#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005341 Py_INCREF(Py_None);
5342 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005343}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005344#endif /* putenv */
5345
Guido van Rossumc524d952001-10-19 01:31:59 +00005346#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005347PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005348"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005349Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005350
5351static PyObject *
5352posix_unsetenv(PyObject *self, PyObject *args)
5353{
5354 char *s1;
5355
5356 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5357 return NULL;
5358
5359 unsetenv(s1);
5360
5361 /* Remove the key from posix_putenv_garbage;
5362 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005363 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005364 * old value was still accessible until then.
5365 */
5366 if (PyDict_DelItem(posix_putenv_garbage,
5367 PyTuple_GET_ITEM(args, 0))) {
5368 /* really not much we can do; just leak */
5369 PyErr_Clear();
5370 }
5371
5372 Py_INCREF(Py_None);
5373 return Py_None;
5374}
5375#endif /* unsetenv */
5376
Guido van Rossumb6a47161997-09-15 22:54:34 +00005377#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005378PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005379"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005381
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005383posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005384{
5385 int code;
5386 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005387 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005388 return NULL;
5389 message = strerror(code);
5390 if (message == NULL) {
5391 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005392 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005393 return NULL;
5394 }
5395 return PyString_FromString(message);
5396}
5397#endif /* strerror */
5398
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005399
Guido van Rossumc9641791998-08-04 15:26:23 +00005400#ifdef HAVE_SYS_WAIT_H
5401
Fred Drake106c1a02002-04-23 15:58:02 +00005402#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005403PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005404"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005405Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005406
5407static PyObject *
5408posix_WCOREDUMP(PyObject *self, PyObject *args)
5409{
5410#ifdef UNION_WAIT
5411 union wait status;
5412#define status_i (status.w_status)
5413#else
5414 int status;
5415#define status_i status
5416#endif
5417 status_i = 0;
5418
5419 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5420 {
5421 return NULL;
5422 }
5423
5424 return PyBool_FromLong(WCOREDUMP(status));
5425#undef status_i
5426}
5427#endif /* WCOREDUMP */
5428
5429#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005430PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005431"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005432Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005433job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005434
5435static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005436posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005437{
5438#ifdef UNION_WAIT
5439 union wait status;
5440#define status_i (status.w_status)
5441#else
5442 int status;
5443#define status_i status
5444#endif
5445 status_i = 0;
5446
5447 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5448 {
5449 return NULL;
5450 }
5451
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005452 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005453#undef status_i
5454}
5455#endif /* WIFCONTINUED */
5456
Guido van Rossumc9641791998-08-04 15:26:23 +00005457#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005458PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005459"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005460Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005461
5462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005463posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005464{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005465#ifdef UNION_WAIT
5466 union wait status;
5467#define status_i (status.w_status)
5468#else
5469 int status;
5470#define status_i status
5471#endif
5472 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005473
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005474 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005475 {
5476 return NULL;
5477 }
Tim Peters5aa91602002-01-30 05:46:57 +00005478
Fred Drake106c1a02002-04-23 15:58:02 +00005479 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005480#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005481}
5482#endif /* WIFSTOPPED */
5483
5484#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005486"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005487Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005488
5489static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005490posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005491{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005492#ifdef UNION_WAIT
5493 union wait status;
5494#define status_i (status.w_status)
5495#else
5496 int status;
5497#define status_i status
5498#endif
5499 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005500
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005501 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005502 {
5503 return NULL;
5504 }
Tim Peters5aa91602002-01-30 05:46:57 +00005505
Fred Drake106c1a02002-04-23 15:58:02 +00005506 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005507#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005508}
5509#endif /* WIFSIGNALED */
5510
5511#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005512PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005513"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005514Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005516
5517static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005518posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005519{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005520#ifdef UNION_WAIT
5521 union wait status;
5522#define status_i (status.w_status)
5523#else
5524 int status;
5525#define status_i status
5526#endif
5527 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005528
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005529 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005530 {
5531 return NULL;
5532 }
Tim Peters5aa91602002-01-30 05:46:57 +00005533
Fred Drake106c1a02002-04-23 15:58:02 +00005534 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005535#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005536}
5537#endif /* WIFEXITED */
5538
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005539#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005540PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005541"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005543
5544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005545posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005546{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005547#ifdef UNION_WAIT
5548 union wait status;
5549#define status_i (status.w_status)
5550#else
5551 int status;
5552#define status_i status
5553#endif
5554 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005555
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005556 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005557 {
5558 return NULL;
5559 }
Tim Peters5aa91602002-01-30 05:46:57 +00005560
Guido van Rossumc9641791998-08-04 15:26:23 +00005561 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005562#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005563}
5564#endif /* WEXITSTATUS */
5565
5566#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005567PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005568"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005569Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005570value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005571
5572static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005573posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005574{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005575#ifdef UNION_WAIT
5576 union wait status;
5577#define status_i (status.w_status)
5578#else
5579 int status;
5580#define status_i status
5581#endif
5582 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005583
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005584 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005585 {
5586 return NULL;
5587 }
Tim Peters5aa91602002-01-30 05:46:57 +00005588
Guido van Rossumc9641791998-08-04 15:26:23 +00005589 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005590#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005591}
5592#endif /* WTERMSIG */
5593
5594#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005595PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005596"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005597Return the signal that stopped the process that provided\n\
5598the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005599
5600static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005601posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005602{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005603#ifdef UNION_WAIT
5604 union wait status;
5605#define status_i (status.w_status)
5606#else
5607 int status;
5608#define status_i status
5609#endif
5610 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005611
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005612 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005613 {
5614 return NULL;
5615 }
Tim Peters5aa91602002-01-30 05:46:57 +00005616
Guido van Rossumc9641791998-08-04 15:26:23 +00005617 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005618#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005619}
5620#endif /* WSTOPSIG */
5621
5622#endif /* HAVE_SYS_WAIT_H */
5623
5624
Guido van Rossum94f6f721999-01-06 18:42:14 +00005625#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005626#ifdef _SCO_DS
5627/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5628 needed definitions in sys/statvfs.h */
5629#define _SVID3
5630#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005631#include <sys/statvfs.h>
5632
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005633static PyObject*
5634_pystatvfs_fromstructstatvfs(struct statvfs st) {
5635 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5636 if (v == NULL)
5637 return NULL;
5638
5639#if !defined(HAVE_LARGEFILE_SUPPORT)
5640 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5641 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5642 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5643 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5644 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5645 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5646 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5647 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5648 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5649 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5650#else
5651 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5652 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005653 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005654 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005655 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005656 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5657 PyStructSequence_SET_ITEM(v, 4,
5658 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005659 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005660 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005661 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005662 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005663 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005664 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5665 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5666 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5667#endif
5668
5669 return v;
5670}
5671
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005672PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005673"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005674Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005675
5676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005677posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005678{
5679 int fd, res;
5680 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005681
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005682 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005683 return NULL;
5684 Py_BEGIN_ALLOW_THREADS
5685 res = fstatvfs(fd, &st);
5686 Py_END_ALLOW_THREADS
5687 if (res != 0)
5688 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005689
5690 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005691}
5692#endif /* HAVE_FSTATVFS */
5693
5694
5695#if defined(HAVE_STATVFS)
5696#include <sys/statvfs.h>
5697
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005698PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005699"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005701
5702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005703posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005704{
5705 char *path;
5706 int res;
5707 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005708 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005709 return NULL;
5710 Py_BEGIN_ALLOW_THREADS
5711 res = statvfs(path, &st);
5712 Py_END_ALLOW_THREADS
5713 if (res != 0)
5714 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005715
5716 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005717}
5718#endif /* HAVE_STATVFS */
5719
5720
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005721#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005722PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005723"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005724Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005725The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005726or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005727
5728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005729posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005730{
5731 PyObject *result = NULL;
5732 char *dir = NULL;
5733 char *pfx = NULL;
5734 char *name;
5735
5736 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5737 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005738
5739 if (PyErr_Warn(PyExc_RuntimeWarning,
5740 "tempnam is a potential security risk to your program") < 0)
5741 return NULL;
5742
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005743#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005744 name = _tempnam(dir, pfx);
5745#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005746 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005747#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005748 if (name == NULL)
5749 return PyErr_NoMemory();
5750 result = PyString_FromString(name);
5751 free(name);
5752 return result;
5753}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005754#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005755
5756
5757#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005758PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005759"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005760Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005761
5762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005763posix_tmpfile(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005764{
5765 FILE *fp;
5766
5767 if (!PyArg_ParseTuple(args, ":tmpfile"))
5768 return NULL;
5769 fp = tmpfile();
5770 if (fp == NULL)
5771 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005772 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005773}
5774#endif
5775
5776
5777#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005778PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005779"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005780Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005781
5782static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005783posix_tmpnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005784{
5785 char buffer[L_tmpnam];
5786 char *name;
5787
5788 if (!PyArg_ParseTuple(args, ":tmpnam"))
5789 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005790
5791 if (PyErr_Warn(PyExc_RuntimeWarning,
5792 "tmpnam is a potential security risk to your program") < 0)
5793 return NULL;
5794
Greg Wardb48bc172000-03-01 21:51:56 +00005795#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005796 name = tmpnam_r(buffer);
5797#else
5798 name = tmpnam(buffer);
5799#endif
5800 if (name == NULL) {
5801 PyErr_SetObject(PyExc_OSError,
5802 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005803#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005804 "unexpected NULL from tmpnam_r"
5805#else
5806 "unexpected NULL from tmpnam"
5807#endif
5808 ));
5809 return NULL;
5810 }
5811 return PyString_FromString(buffer);
5812}
5813#endif
5814
5815
Fred Drakec9680921999-12-13 16:37:25 +00005816/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5817 * It maps strings representing configuration variable names to
5818 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005819 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005820 * rarely-used constants. There are three separate tables that use
5821 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005822 *
5823 * This code is always included, even if none of the interfaces that
5824 * need it are included. The #if hackery needed to avoid it would be
5825 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005826 */
5827struct constdef {
5828 char *name;
5829 long value;
5830};
5831
Fred Drake12c6e2d1999-12-14 21:25:03 +00005832static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005833conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5834 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005835{
5836 if (PyInt_Check(arg)) {
5837 *valuep = PyInt_AS_LONG(arg);
5838 return 1;
5839 }
5840 if (PyString_Check(arg)) {
5841 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005842 size_t lo = 0;
5843 size_t mid;
5844 size_t hi = tablesize;
5845 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005846 char *confname = PyString_AS_STRING(arg);
5847 while (lo < hi) {
5848 mid = (lo + hi) / 2;
5849 cmp = strcmp(confname, table[mid].name);
5850 if (cmp < 0)
5851 hi = mid;
5852 else if (cmp > 0)
5853 lo = mid + 1;
5854 else {
5855 *valuep = table[mid].value;
5856 return 1;
5857 }
5858 }
5859 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
5860 }
5861 else
5862 PyErr_SetString(PyExc_TypeError,
5863 "configuration names must be strings or integers");
5864 return 0;
5865}
5866
5867
5868#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5869static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005870#ifdef _PC_ABI_AIO_XFER_MAX
5871 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
5872#endif
5873#ifdef _PC_ABI_ASYNC_IO
5874 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
5875#endif
Fred Drakec9680921999-12-13 16:37:25 +00005876#ifdef _PC_ASYNC_IO
5877 {"PC_ASYNC_IO", _PC_ASYNC_IO},
5878#endif
5879#ifdef _PC_CHOWN_RESTRICTED
5880 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
5881#endif
5882#ifdef _PC_FILESIZEBITS
5883 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
5884#endif
5885#ifdef _PC_LAST
5886 {"PC_LAST", _PC_LAST},
5887#endif
5888#ifdef _PC_LINK_MAX
5889 {"PC_LINK_MAX", _PC_LINK_MAX},
5890#endif
5891#ifdef _PC_MAX_CANON
5892 {"PC_MAX_CANON", _PC_MAX_CANON},
5893#endif
5894#ifdef _PC_MAX_INPUT
5895 {"PC_MAX_INPUT", _PC_MAX_INPUT},
5896#endif
5897#ifdef _PC_NAME_MAX
5898 {"PC_NAME_MAX", _PC_NAME_MAX},
5899#endif
5900#ifdef _PC_NO_TRUNC
5901 {"PC_NO_TRUNC", _PC_NO_TRUNC},
5902#endif
5903#ifdef _PC_PATH_MAX
5904 {"PC_PATH_MAX", _PC_PATH_MAX},
5905#endif
5906#ifdef _PC_PIPE_BUF
5907 {"PC_PIPE_BUF", _PC_PIPE_BUF},
5908#endif
5909#ifdef _PC_PRIO_IO
5910 {"PC_PRIO_IO", _PC_PRIO_IO},
5911#endif
5912#ifdef _PC_SOCK_MAXBUF
5913 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
5914#endif
5915#ifdef _PC_SYNC_IO
5916 {"PC_SYNC_IO", _PC_SYNC_IO},
5917#endif
5918#ifdef _PC_VDISABLE
5919 {"PC_VDISABLE", _PC_VDISABLE},
5920#endif
5921};
5922
Fred Drakec9680921999-12-13 16:37:25 +00005923static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005924conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00005925{
5926 return conv_confname(arg, valuep, posix_constants_pathconf,
5927 sizeof(posix_constants_pathconf)
5928 / sizeof(struct constdef));
5929}
5930#endif
5931
5932#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005933PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005934"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005935Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005936If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005937
5938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005939posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005940{
5941 PyObject *result = NULL;
5942 int name, fd;
5943
Fred Drake12c6e2d1999-12-14 21:25:03 +00005944 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
5945 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00005946 long limit;
5947
5948 errno = 0;
5949 limit = fpathconf(fd, name);
5950 if (limit == -1 && errno != 0)
5951 posix_error();
5952 else
5953 result = PyInt_FromLong(limit);
5954 }
5955 return result;
5956}
5957#endif
5958
5959
5960#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005961PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005962"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00005963Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005964If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00005965
5966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005967posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00005968{
5969 PyObject *result = NULL;
5970 int name;
5971 char *path;
5972
5973 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
5974 conv_path_confname, &name)) {
5975 long limit;
5976
5977 errno = 0;
5978 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005979 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00005980 if (errno == EINVAL)
5981 /* could be a path or name problem */
5982 posix_error();
5983 else
5984 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00005985 }
Fred Drakec9680921999-12-13 16:37:25 +00005986 else
5987 result = PyInt_FromLong(limit);
5988 }
5989 return result;
5990}
5991#endif
5992
5993#ifdef HAVE_CONFSTR
5994static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00005995#ifdef _CS_ARCHITECTURE
5996 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
5997#endif
5998#ifdef _CS_HOSTNAME
5999 {"CS_HOSTNAME", _CS_HOSTNAME},
6000#endif
6001#ifdef _CS_HW_PROVIDER
6002 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6003#endif
6004#ifdef _CS_HW_SERIAL
6005 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6006#endif
6007#ifdef _CS_INITTAB_NAME
6008 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6009#endif
Fred Drakec9680921999-12-13 16:37:25 +00006010#ifdef _CS_LFS64_CFLAGS
6011 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6012#endif
6013#ifdef _CS_LFS64_LDFLAGS
6014 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6015#endif
6016#ifdef _CS_LFS64_LIBS
6017 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6018#endif
6019#ifdef _CS_LFS64_LINTFLAGS
6020 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6021#endif
6022#ifdef _CS_LFS_CFLAGS
6023 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6024#endif
6025#ifdef _CS_LFS_LDFLAGS
6026 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6027#endif
6028#ifdef _CS_LFS_LIBS
6029 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6030#endif
6031#ifdef _CS_LFS_LINTFLAGS
6032 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6033#endif
Fred Draked86ed291999-12-15 15:34:33 +00006034#ifdef _CS_MACHINE
6035 {"CS_MACHINE", _CS_MACHINE},
6036#endif
Fred Drakec9680921999-12-13 16:37:25 +00006037#ifdef _CS_PATH
6038 {"CS_PATH", _CS_PATH},
6039#endif
Fred Draked86ed291999-12-15 15:34:33 +00006040#ifdef _CS_RELEASE
6041 {"CS_RELEASE", _CS_RELEASE},
6042#endif
6043#ifdef _CS_SRPC_DOMAIN
6044 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6045#endif
6046#ifdef _CS_SYSNAME
6047 {"CS_SYSNAME", _CS_SYSNAME},
6048#endif
6049#ifdef _CS_VERSION
6050 {"CS_VERSION", _CS_VERSION},
6051#endif
Fred Drakec9680921999-12-13 16:37:25 +00006052#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6053 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6054#endif
6055#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6056 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6057#endif
6058#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6059 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6060#endif
6061#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6062 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6063#endif
6064#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6065 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6066#endif
6067#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6068 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6069#endif
6070#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6071 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6072#endif
6073#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6074 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6075#endif
6076#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6077 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6078#endif
6079#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6080 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6081#endif
6082#ifdef _CS_XBS5_LP64_OFF64_LIBS
6083 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6084#endif
6085#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6086 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6087#endif
6088#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6089 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6090#endif
6091#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6092 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6093#endif
6094#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6095 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6096#endif
6097#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6098 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6099#endif
Fred Draked86ed291999-12-15 15:34:33 +00006100#ifdef _MIPS_CS_AVAIL_PROCESSORS
6101 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6102#endif
6103#ifdef _MIPS_CS_BASE
6104 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6105#endif
6106#ifdef _MIPS_CS_HOSTID
6107 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6108#endif
6109#ifdef _MIPS_CS_HW_NAME
6110 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6111#endif
6112#ifdef _MIPS_CS_NUM_PROCESSORS
6113 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6114#endif
6115#ifdef _MIPS_CS_OSREL_MAJ
6116 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6117#endif
6118#ifdef _MIPS_CS_OSREL_MIN
6119 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6120#endif
6121#ifdef _MIPS_CS_OSREL_PATCH
6122 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6123#endif
6124#ifdef _MIPS_CS_OS_NAME
6125 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6126#endif
6127#ifdef _MIPS_CS_OS_PROVIDER
6128 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6129#endif
6130#ifdef _MIPS_CS_PROCESSORS
6131 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6132#endif
6133#ifdef _MIPS_CS_SERIAL
6134 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6135#endif
6136#ifdef _MIPS_CS_VENDOR
6137 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6138#endif
Fred Drakec9680921999-12-13 16:37:25 +00006139};
6140
6141static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006142conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006143{
6144 return conv_confname(arg, valuep, posix_constants_confstr,
6145 sizeof(posix_constants_confstr)
6146 / sizeof(struct constdef));
6147}
6148
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006150"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006151Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006152
6153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006154posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006155{
6156 PyObject *result = NULL;
6157 int name;
6158 char buffer[64];
6159
6160 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6161 int len = confstr(name, buffer, sizeof(buffer));
6162
Fred Drakec9680921999-12-13 16:37:25 +00006163 errno = 0;
6164 if (len == 0) {
6165 if (errno != 0)
6166 posix_error();
6167 else
6168 result = PyString_FromString("");
6169 }
6170 else {
6171 if (len >= sizeof(buffer)) {
6172 result = PyString_FromStringAndSize(NULL, len);
6173 if (result != NULL)
6174 confstr(name, PyString_AS_STRING(result), len+1);
6175 }
6176 else
6177 result = PyString_FromString(buffer);
6178 }
6179 }
6180 return result;
6181}
6182#endif
6183
6184
6185#ifdef HAVE_SYSCONF
6186static struct constdef posix_constants_sysconf[] = {
6187#ifdef _SC_2_CHAR_TERM
6188 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6189#endif
6190#ifdef _SC_2_C_BIND
6191 {"SC_2_C_BIND", _SC_2_C_BIND},
6192#endif
6193#ifdef _SC_2_C_DEV
6194 {"SC_2_C_DEV", _SC_2_C_DEV},
6195#endif
6196#ifdef _SC_2_C_VERSION
6197 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6198#endif
6199#ifdef _SC_2_FORT_DEV
6200 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6201#endif
6202#ifdef _SC_2_FORT_RUN
6203 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6204#endif
6205#ifdef _SC_2_LOCALEDEF
6206 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6207#endif
6208#ifdef _SC_2_SW_DEV
6209 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6210#endif
6211#ifdef _SC_2_UPE
6212 {"SC_2_UPE", _SC_2_UPE},
6213#endif
6214#ifdef _SC_2_VERSION
6215 {"SC_2_VERSION", _SC_2_VERSION},
6216#endif
Fred Draked86ed291999-12-15 15:34:33 +00006217#ifdef _SC_ABI_ASYNCHRONOUS_IO
6218 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6219#endif
6220#ifdef _SC_ACL
6221 {"SC_ACL", _SC_ACL},
6222#endif
Fred Drakec9680921999-12-13 16:37:25 +00006223#ifdef _SC_AIO_LISTIO_MAX
6224 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6225#endif
Fred Drakec9680921999-12-13 16:37:25 +00006226#ifdef _SC_AIO_MAX
6227 {"SC_AIO_MAX", _SC_AIO_MAX},
6228#endif
6229#ifdef _SC_AIO_PRIO_DELTA_MAX
6230 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6231#endif
6232#ifdef _SC_ARG_MAX
6233 {"SC_ARG_MAX", _SC_ARG_MAX},
6234#endif
6235#ifdef _SC_ASYNCHRONOUS_IO
6236 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6237#endif
6238#ifdef _SC_ATEXIT_MAX
6239 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6240#endif
Fred Draked86ed291999-12-15 15:34:33 +00006241#ifdef _SC_AUDIT
6242 {"SC_AUDIT", _SC_AUDIT},
6243#endif
Fred Drakec9680921999-12-13 16:37:25 +00006244#ifdef _SC_AVPHYS_PAGES
6245 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6246#endif
6247#ifdef _SC_BC_BASE_MAX
6248 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6249#endif
6250#ifdef _SC_BC_DIM_MAX
6251 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6252#endif
6253#ifdef _SC_BC_SCALE_MAX
6254 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6255#endif
6256#ifdef _SC_BC_STRING_MAX
6257 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6258#endif
Fred Draked86ed291999-12-15 15:34:33 +00006259#ifdef _SC_CAP
6260 {"SC_CAP", _SC_CAP},
6261#endif
Fred Drakec9680921999-12-13 16:37:25 +00006262#ifdef _SC_CHARCLASS_NAME_MAX
6263 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6264#endif
6265#ifdef _SC_CHAR_BIT
6266 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6267#endif
6268#ifdef _SC_CHAR_MAX
6269 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6270#endif
6271#ifdef _SC_CHAR_MIN
6272 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6273#endif
6274#ifdef _SC_CHILD_MAX
6275 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6276#endif
6277#ifdef _SC_CLK_TCK
6278 {"SC_CLK_TCK", _SC_CLK_TCK},
6279#endif
6280#ifdef _SC_COHER_BLKSZ
6281 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6282#endif
6283#ifdef _SC_COLL_WEIGHTS_MAX
6284 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6285#endif
6286#ifdef _SC_DCACHE_ASSOC
6287 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6288#endif
6289#ifdef _SC_DCACHE_BLKSZ
6290 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6291#endif
6292#ifdef _SC_DCACHE_LINESZ
6293 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6294#endif
6295#ifdef _SC_DCACHE_SZ
6296 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6297#endif
6298#ifdef _SC_DCACHE_TBLKSZ
6299 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6300#endif
6301#ifdef _SC_DELAYTIMER_MAX
6302 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6303#endif
6304#ifdef _SC_EQUIV_CLASS_MAX
6305 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6306#endif
6307#ifdef _SC_EXPR_NEST_MAX
6308 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6309#endif
6310#ifdef _SC_FSYNC
6311 {"SC_FSYNC", _SC_FSYNC},
6312#endif
6313#ifdef _SC_GETGR_R_SIZE_MAX
6314 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6315#endif
6316#ifdef _SC_GETPW_R_SIZE_MAX
6317 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6318#endif
6319#ifdef _SC_ICACHE_ASSOC
6320 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6321#endif
6322#ifdef _SC_ICACHE_BLKSZ
6323 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6324#endif
6325#ifdef _SC_ICACHE_LINESZ
6326 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6327#endif
6328#ifdef _SC_ICACHE_SZ
6329 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6330#endif
Fred Draked86ed291999-12-15 15:34:33 +00006331#ifdef _SC_INF
6332 {"SC_INF", _SC_INF},
6333#endif
Fred Drakec9680921999-12-13 16:37:25 +00006334#ifdef _SC_INT_MAX
6335 {"SC_INT_MAX", _SC_INT_MAX},
6336#endif
6337#ifdef _SC_INT_MIN
6338 {"SC_INT_MIN", _SC_INT_MIN},
6339#endif
6340#ifdef _SC_IOV_MAX
6341 {"SC_IOV_MAX", _SC_IOV_MAX},
6342#endif
Fred Draked86ed291999-12-15 15:34:33 +00006343#ifdef _SC_IP_SECOPTS
6344 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6345#endif
Fred Drakec9680921999-12-13 16:37:25 +00006346#ifdef _SC_JOB_CONTROL
6347 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6348#endif
Fred Draked86ed291999-12-15 15:34:33 +00006349#ifdef _SC_KERN_POINTERS
6350 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6351#endif
6352#ifdef _SC_KERN_SIM
6353 {"SC_KERN_SIM", _SC_KERN_SIM},
6354#endif
Fred Drakec9680921999-12-13 16:37:25 +00006355#ifdef _SC_LINE_MAX
6356 {"SC_LINE_MAX", _SC_LINE_MAX},
6357#endif
6358#ifdef _SC_LOGIN_NAME_MAX
6359 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6360#endif
6361#ifdef _SC_LOGNAME_MAX
6362 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6363#endif
6364#ifdef _SC_LONG_BIT
6365 {"SC_LONG_BIT", _SC_LONG_BIT},
6366#endif
Fred Draked86ed291999-12-15 15:34:33 +00006367#ifdef _SC_MAC
6368 {"SC_MAC", _SC_MAC},
6369#endif
Fred Drakec9680921999-12-13 16:37:25 +00006370#ifdef _SC_MAPPED_FILES
6371 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6372#endif
6373#ifdef _SC_MAXPID
6374 {"SC_MAXPID", _SC_MAXPID},
6375#endif
6376#ifdef _SC_MB_LEN_MAX
6377 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6378#endif
6379#ifdef _SC_MEMLOCK
6380 {"SC_MEMLOCK", _SC_MEMLOCK},
6381#endif
6382#ifdef _SC_MEMLOCK_RANGE
6383 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6384#endif
6385#ifdef _SC_MEMORY_PROTECTION
6386 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6387#endif
6388#ifdef _SC_MESSAGE_PASSING
6389 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6390#endif
Fred Draked86ed291999-12-15 15:34:33 +00006391#ifdef _SC_MMAP_FIXED_ALIGNMENT
6392 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6393#endif
Fred Drakec9680921999-12-13 16:37:25 +00006394#ifdef _SC_MQ_OPEN_MAX
6395 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6396#endif
6397#ifdef _SC_MQ_PRIO_MAX
6398 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6399#endif
Fred Draked86ed291999-12-15 15:34:33 +00006400#ifdef _SC_NACLS_MAX
6401 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6402#endif
Fred Drakec9680921999-12-13 16:37:25 +00006403#ifdef _SC_NGROUPS_MAX
6404 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6405#endif
6406#ifdef _SC_NL_ARGMAX
6407 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6408#endif
6409#ifdef _SC_NL_LANGMAX
6410 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6411#endif
6412#ifdef _SC_NL_MSGMAX
6413 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6414#endif
6415#ifdef _SC_NL_NMAX
6416 {"SC_NL_NMAX", _SC_NL_NMAX},
6417#endif
6418#ifdef _SC_NL_SETMAX
6419 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6420#endif
6421#ifdef _SC_NL_TEXTMAX
6422 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6423#endif
6424#ifdef _SC_NPROCESSORS_CONF
6425 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6426#endif
6427#ifdef _SC_NPROCESSORS_ONLN
6428 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6429#endif
Fred Draked86ed291999-12-15 15:34:33 +00006430#ifdef _SC_NPROC_CONF
6431 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6432#endif
6433#ifdef _SC_NPROC_ONLN
6434 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6435#endif
Fred Drakec9680921999-12-13 16:37:25 +00006436#ifdef _SC_NZERO
6437 {"SC_NZERO", _SC_NZERO},
6438#endif
6439#ifdef _SC_OPEN_MAX
6440 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6441#endif
6442#ifdef _SC_PAGESIZE
6443 {"SC_PAGESIZE", _SC_PAGESIZE},
6444#endif
6445#ifdef _SC_PAGE_SIZE
6446 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6447#endif
6448#ifdef _SC_PASS_MAX
6449 {"SC_PASS_MAX", _SC_PASS_MAX},
6450#endif
6451#ifdef _SC_PHYS_PAGES
6452 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6453#endif
6454#ifdef _SC_PII
6455 {"SC_PII", _SC_PII},
6456#endif
6457#ifdef _SC_PII_INTERNET
6458 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6459#endif
6460#ifdef _SC_PII_INTERNET_DGRAM
6461 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6462#endif
6463#ifdef _SC_PII_INTERNET_STREAM
6464 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6465#endif
6466#ifdef _SC_PII_OSI
6467 {"SC_PII_OSI", _SC_PII_OSI},
6468#endif
6469#ifdef _SC_PII_OSI_CLTS
6470 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6471#endif
6472#ifdef _SC_PII_OSI_COTS
6473 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6474#endif
6475#ifdef _SC_PII_OSI_M
6476 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6477#endif
6478#ifdef _SC_PII_SOCKET
6479 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6480#endif
6481#ifdef _SC_PII_XTI
6482 {"SC_PII_XTI", _SC_PII_XTI},
6483#endif
6484#ifdef _SC_POLL
6485 {"SC_POLL", _SC_POLL},
6486#endif
6487#ifdef _SC_PRIORITIZED_IO
6488 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6489#endif
6490#ifdef _SC_PRIORITY_SCHEDULING
6491 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6492#endif
6493#ifdef _SC_REALTIME_SIGNALS
6494 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6495#endif
6496#ifdef _SC_RE_DUP_MAX
6497 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6498#endif
6499#ifdef _SC_RTSIG_MAX
6500 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6501#endif
6502#ifdef _SC_SAVED_IDS
6503 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6504#endif
6505#ifdef _SC_SCHAR_MAX
6506 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6507#endif
6508#ifdef _SC_SCHAR_MIN
6509 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6510#endif
6511#ifdef _SC_SELECT
6512 {"SC_SELECT", _SC_SELECT},
6513#endif
6514#ifdef _SC_SEMAPHORES
6515 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6516#endif
6517#ifdef _SC_SEM_NSEMS_MAX
6518 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6519#endif
6520#ifdef _SC_SEM_VALUE_MAX
6521 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6522#endif
6523#ifdef _SC_SHARED_MEMORY_OBJECTS
6524 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6525#endif
6526#ifdef _SC_SHRT_MAX
6527 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6528#endif
6529#ifdef _SC_SHRT_MIN
6530 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6531#endif
6532#ifdef _SC_SIGQUEUE_MAX
6533 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6534#endif
6535#ifdef _SC_SIGRT_MAX
6536 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6537#endif
6538#ifdef _SC_SIGRT_MIN
6539 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6540#endif
Fred Draked86ed291999-12-15 15:34:33 +00006541#ifdef _SC_SOFTPOWER
6542 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6543#endif
Fred Drakec9680921999-12-13 16:37:25 +00006544#ifdef _SC_SPLIT_CACHE
6545 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6546#endif
6547#ifdef _SC_SSIZE_MAX
6548 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6549#endif
6550#ifdef _SC_STACK_PROT
6551 {"SC_STACK_PROT", _SC_STACK_PROT},
6552#endif
6553#ifdef _SC_STREAM_MAX
6554 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6555#endif
6556#ifdef _SC_SYNCHRONIZED_IO
6557 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6558#endif
6559#ifdef _SC_THREADS
6560 {"SC_THREADS", _SC_THREADS},
6561#endif
6562#ifdef _SC_THREAD_ATTR_STACKADDR
6563 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6564#endif
6565#ifdef _SC_THREAD_ATTR_STACKSIZE
6566 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6567#endif
6568#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6569 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6570#endif
6571#ifdef _SC_THREAD_KEYS_MAX
6572 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6573#endif
6574#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6575 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6576#endif
6577#ifdef _SC_THREAD_PRIO_INHERIT
6578 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6579#endif
6580#ifdef _SC_THREAD_PRIO_PROTECT
6581 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6582#endif
6583#ifdef _SC_THREAD_PROCESS_SHARED
6584 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6585#endif
6586#ifdef _SC_THREAD_SAFE_FUNCTIONS
6587 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6588#endif
6589#ifdef _SC_THREAD_STACK_MIN
6590 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6591#endif
6592#ifdef _SC_THREAD_THREADS_MAX
6593 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6594#endif
6595#ifdef _SC_TIMERS
6596 {"SC_TIMERS", _SC_TIMERS},
6597#endif
6598#ifdef _SC_TIMER_MAX
6599 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6600#endif
6601#ifdef _SC_TTY_NAME_MAX
6602 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6603#endif
6604#ifdef _SC_TZNAME_MAX
6605 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6606#endif
6607#ifdef _SC_T_IOV_MAX
6608 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6609#endif
6610#ifdef _SC_UCHAR_MAX
6611 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6612#endif
6613#ifdef _SC_UINT_MAX
6614 {"SC_UINT_MAX", _SC_UINT_MAX},
6615#endif
6616#ifdef _SC_UIO_MAXIOV
6617 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6618#endif
6619#ifdef _SC_ULONG_MAX
6620 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6621#endif
6622#ifdef _SC_USHRT_MAX
6623 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6624#endif
6625#ifdef _SC_VERSION
6626 {"SC_VERSION", _SC_VERSION},
6627#endif
6628#ifdef _SC_WORD_BIT
6629 {"SC_WORD_BIT", _SC_WORD_BIT},
6630#endif
6631#ifdef _SC_XBS5_ILP32_OFF32
6632 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6633#endif
6634#ifdef _SC_XBS5_ILP32_OFFBIG
6635 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6636#endif
6637#ifdef _SC_XBS5_LP64_OFF64
6638 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6639#endif
6640#ifdef _SC_XBS5_LPBIG_OFFBIG
6641 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6642#endif
6643#ifdef _SC_XOPEN_CRYPT
6644 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6645#endif
6646#ifdef _SC_XOPEN_ENH_I18N
6647 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6648#endif
6649#ifdef _SC_XOPEN_LEGACY
6650 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6651#endif
6652#ifdef _SC_XOPEN_REALTIME
6653 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6654#endif
6655#ifdef _SC_XOPEN_REALTIME_THREADS
6656 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6657#endif
6658#ifdef _SC_XOPEN_SHM
6659 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6660#endif
6661#ifdef _SC_XOPEN_UNIX
6662 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6663#endif
6664#ifdef _SC_XOPEN_VERSION
6665 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6666#endif
6667#ifdef _SC_XOPEN_XCU_VERSION
6668 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6669#endif
6670#ifdef _SC_XOPEN_XPG2
6671 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6672#endif
6673#ifdef _SC_XOPEN_XPG3
6674 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6675#endif
6676#ifdef _SC_XOPEN_XPG4
6677 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6678#endif
6679};
6680
6681static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006682conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006683{
6684 return conv_confname(arg, valuep, posix_constants_sysconf,
6685 sizeof(posix_constants_sysconf)
6686 / sizeof(struct constdef));
6687}
6688
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006689PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006690"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006691Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006692
6693static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006694posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006695{
6696 PyObject *result = NULL;
6697 int name;
6698
6699 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6700 int value;
6701
6702 errno = 0;
6703 value = sysconf(name);
6704 if (value == -1 && errno != 0)
6705 posix_error();
6706 else
6707 result = PyInt_FromLong(value);
6708 }
6709 return result;
6710}
6711#endif
6712
6713
Fred Drakebec628d1999-12-15 18:31:10 +00006714/* This code is used to ensure that the tables of configuration value names
6715 * are in sorted order as required by conv_confname(), and also to build the
6716 * the exported dictionaries that are used to publish information about the
6717 * names available on the host platform.
6718 *
6719 * Sorting the table at runtime ensures that the table is properly ordered
6720 * when used, even for platforms we're not able to test on. It also makes
6721 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006722 */
Fred Drakebec628d1999-12-15 18:31:10 +00006723
6724static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006725cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006726{
6727 const struct constdef *c1 =
6728 (const struct constdef *) v1;
6729 const struct constdef *c2 =
6730 (const struct constdef *) v2;
6731
6732 return strcmp(c1->name, c2->name);
6733}
6734
6735static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006736setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006737 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006738{
Fred Drakebec628d1999-12-15 18:31:10 +00006739 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006740 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006741
6742 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6743 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006744 if (d == NULL)
6745 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006746
Barry Warsaw3155db32000-04-13 15:20:40 +00006747 for (i=0; i < tablesize; ++i) {
6748 PyObject *o = PyInt_FromLong(table[i].value);
6749 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6750 Py_XDECREF(o);
6751 Py_DECREF(d);
6752 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006753 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006754 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006755 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006756 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006757}
6758
Fred Drakebec628d1999-12-15 18:31:10 +00006759/* Return -1 on failure, 0 on success. */
6760static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006761setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006762{
6763#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006764 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006765 sizeof(posix_constants_pathconf)
6766 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006767 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006768 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006769#endif
6770#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006771 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006772 sizeof(posix_constants_confstr)
6773 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006774 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006775 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006776#endif
6777#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006778 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006779 sizeof(posix_constants_sysconf)
6780 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006781 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006782 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006783#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006784 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006785}
Fred Draked86ed291999-12-15 15:34:33 +00006786
6787
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006788PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006789"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006790Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006791in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006792
6793static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006794posix_abort(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006795{
6796 if (!PyArg_ParseTuple(args, ":abort"))
6797 return NULL;
6798 abort();
6799 /*NOTREACHED*/
6800 Py_FatalError("abort() called from Python code didn't abort!");
6801 return NULL;
6802}
Fred Drakebec628d1999-12-15 18:31:10 +00006803
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006804#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006805PyDoc_STRVAR(win32_startfile__doc__,
6806"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006807\n\
6808This acts like double-clicking the file in Explorer, or giving the file\n\
6809name as an argument to the DOS \"start\" command: the file is opened\n\
6810with whatever application (if any) its extension is associated.\n\
6811\n\
6812startfile returns as soon as the associated application is launched.\n\
6813There is no option to wait for the application to close, and no way\n\
6814to retrieve the application's exit status.\n\
6815\n\
6816The filepath is relative to the current directory. If you want to use\n\
6817an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006818the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006819
6820static PyObject *
6821win32_startfile(PyObject *self, PyObject *args)
6822{
6823 char *filepath;
6824 HINSTANCE rc;
6825 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6826 return NULL;
6827 Py_BEGIN_ALLOW_THREADS
6828 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6829 Py_END_ALLOW_THREADS
6830 if (rc <= (HINSTANCE)32)
6831 return win32_error("startfile", filepath);
6832 Py_INCREF(Py_None);
6833 return Py_None;
6834}
6835#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006836
6837static PyMethodDef posix_methods[] = {
6838 {"access", posix_access, METH_VARARGS, posix_access__doc__},
6839#ifdef HAVE_TTYNAME
6840 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
6841#endif
6842 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
6843 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006844#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006845 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006846#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00006847#ifdef HAVE_LCHOWN
6848 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
6849#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00006850#ifdef HAVE_CHROOT
6851 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
6852#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006853#ifdef HAVE_CTERMID
6854 {"ctermid", posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
6855#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00006856#ifdef HAVE_GETCWD
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006857 {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006858 {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00006859#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00006860#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006861 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006862#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006863 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
6864 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
6865 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006866#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006867 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006868#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006869#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006870 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006871#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006872 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
6873 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
6874 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00006875 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006876#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006877 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006878#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006879#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006880 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006881#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006882 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006883#ifdef HAVE_UNAME
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006884 {"uname", posix_uname, METH_VARARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006885#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006886 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
6887 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
6888 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006889#ifdef HAVE_TIMES
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006890 {"times", posix_times, METH_VARARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006891#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006892 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006893#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006894 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
6895 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006896#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00006897#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006898 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
6899 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00006900#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00006901#ifdef HAVE_FORK1
6902 {"fork1", posix_fork1, METH_VARARGS, posix_fork1__doc__},
6903#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006904#ifdef HAVE_FORK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006905 {"fork", posix_fork, METH_VARARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006906#endif /* HAVE_FORK */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006907#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
Fred Drake8cef4cf2000-06-28 16:40:38 +00006908 {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__},
Thomas Wouters70c21a12000-07-14 14:28:33 +00006909#endif /* HAVE_OPENPTY || HAVE__GETPTY */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006910#ifdef HAVE_FORKPTY
6911 {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
6912#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006913#ifdef HAVE_GETEGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006914 {"getegid", posix_getegid, METH_VARARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006915#endif /* HAVE_GETEGID */
6916#ifdef HAVE_GETEUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006917 {"geteuid", posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006918#endif /* HAVE_GETEUID */
6919#ifdef HAVE_GETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006920 {"getgid", posix_getgid, METH_VARARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006921#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00006922#ifdef HAVE_GETGROUPS
6923 {"getgroups", posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
6924#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006925 {"getpid", posix_getpid, METH_VARARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00006926#ifdef HAVE_GETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006927 {"getpgrp", posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006928#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006929#ifdef HAVE_GETPPID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006930 {"getppid", posix_getppid, METH_VARARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006931#endif /* HAVE_GETPPID */
6932#ifdef HAVE_GETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006933 {"getuid", posix_getuid, METH_VARARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006934#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006935#ifdef HAVE_GETLOGIN
6936 {"getlogin", posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
6937#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00006938#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006939 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006940#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00006941#ifdef HAVE_KILLPG
6942 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
6943#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00006944#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006945 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00006946#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006947#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006948 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006949#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006950 {"popen2", win32_popen2, METH_VARARGS},
6951 {"popen3", win32_popen3, METH_VARARGS},
6952 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00006953 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006954#else
6955#if defined(PYOS_OS2) && defined(PYCC_GCC)
6956 {"popen2", os2emx_popen2, METH_VARARGS},
6957 {"popen3", os2emx_popen3, METH_VARARGS},
6958 {"popen4", os2emx_popen4, METH_VARARGS},
6959#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006960#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006961#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006962#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006963 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006964#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006965#ifdef HAVE_SETEUID
6966 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
6967#endif /* HAVE_SETEUID */
6968#ifdef HAVE_SETEGID
6969 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
6970#endif /* HAVE_SETEGID */
6971#ifdef HAVE_SETREUID
6972 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
6973#endif /* HAVE_SETREUID */
6974#ifdef HAVE_SETREGID
6975 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
6976#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006977#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006978 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006979#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006980#ifdef HAVE_SETGROUPS
6981 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
6982#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00006983#ifdef HAVE_GETPGID
6984 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
6985#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006986#ifdef HAVE_SETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006987 {"setpgrp", posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006988#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00006989#ifdef HAVE_WAIT
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006990 {"wait", posix_wait, METH_VARARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00006991#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00006992#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006993 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006994#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006995#ifdef HAVE_SETSID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006996 {"setsid", posix_setsid, METH_VARARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006997#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00006998#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006999 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007000#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007001#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007002 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007003#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007004#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007005 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007006#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007007 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7008 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7009 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7010 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7011 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7012 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7013 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7014 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7015 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007016 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007017#ifdef HAVE_PIPE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007018 {"pipe", posix_pipe, METH_VARARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007019#endif
7020#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007021 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007022#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007023#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007024 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7025#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007026#ifdef HAVE_DEVICE_MACROS
7027 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7028 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7029 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7030#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007031#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007032 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007033#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007034#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007035 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007036#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007037#ifdef HAVE_UNSETENV
7038 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7039#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007040#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007041 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007042#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007043#ifdef HAVE_FCHDIR
7044 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7045#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007046#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007047 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007048#endif
7049#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007050 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007051#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007052#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007053#ifdef WCOREDUMP
7054 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7055#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007056#ifdef WIFCONTINUED
7057 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7058#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007059#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007060 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007061#endif /* WIFSTOPPED */
7062#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007063 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007064#endif /* WIFSIGNALED */
7065#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007066 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007067#endif /* WIFEXITED */
7068#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007069 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007070#endif /* WEXITSTATUS */
7071#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007072 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007073#endif /* WTERMSIG */
7074#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007075 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007076#endif /* WSTOPSIG */
7077#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007078#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007079 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007080#endif
7081#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007082 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007083#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007084#ifdef HAVE_TMPFILE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007085 {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
7086#endif
7087#ifdef HAVE_TEMPNAM
7088 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7089#endif
7090#ifdef HAVE_TMPNAM
7091 {"tmpnam", posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
7092#endif
Fred Drakec9680921999-12-13 16:37:25 +00007093#ifdef HAVE_CONFSTR
7094 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7095#endif
7096#ifdef HAVE_SYSCONF
7097 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7098#endif
7099#ifdef HAVE_FPATHCONF
7100 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7101#endif
7102#ifdef HAVE_PATHCONF
7103 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7104#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007105 {"abort", posix_abort, METH_VARARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007106#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007107 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7108#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007109 {NULL, NULL} /* Sentinel */
7110};
7111
7112
Barry Warsaw4a342091996-12-19 23:50:02 +00007113static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007114ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007115{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007116 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007117}
7118
Guido van Rossumd48f2521997-12-05 22:19:34 +00007119#if defined(PYOS_OS2)
7120/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007121static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007122{
7123 APIRET rc;
7124 ULONG values[QSV_MAX+1];
7125 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007126 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007127
7128 Py_BEGIN_ALLOW_THREADS
7129 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7130 Py_END_ALLOW_THREADS
7131
7132 if (rc != NO_ERROR) {
7133 os2_error(rc);
7134 return -1;
7135 }
7136
Fred Drake4d1e64b2002-04-15 19:40:07 +00007137 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7138 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7139 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7140 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7141 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7142 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7143 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007144
7145 switch (values[QSV_VERSION_MINOR]) {
7146 case 0: ver = "2.00"; break;
7147 case 10: ver = "2.10"; break;
7148 case 11: ver = "2.11"; break;
7149 case 30: ver = "3.00"; break;
7150 case 40: ver = "4.00"; break;
7151 case 50: ver = "5.00"; break;
7152 default:
Tim Peters885d4572001-11-28 20:27:42 +00007153 PyOS_snprintf(tmp, sizeof(tmp),
7154 "%d-%d", values[QSV_VERSION_MAJOR],
7155 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007156 ver = &tmp[0];
7157 }
7158
7159 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007160 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007161 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007162
7163 /* Add Indicator of Which Drive was Used to Boot the System */
7164 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7165 tmp[1] = ':';
7166 tmp[2] = '\0';
7167
Fred Drake4d1e64b2002-04-15 19:40:07 +00007168 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007169}
7170#endif
7171
Barry Warsaw4a342091996-12-19 23:50:02 +00007172static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007173all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007174{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007175#ifdef F_OK
7176 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007177#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007178#ifdef R_OK
7179 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007180#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007181#ifdef W_OK
7182 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007183#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007184#ifdef X_OK
7185 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007186#endif
Fred Drakec9680921999-12-13 16:37:25 +00007187#ifdef NGROUPS_MAX
7188 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7189#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007190#ifdef TMP_MAX
7191 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7192#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007193#ifdef WCONTINUED
7194 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7195#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007196#ifdef WNOHANG
7197 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007198#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007199#ifdef WUNTRACED
7200 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7201#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007202#ifdef O_RDONLY
7203 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7204#endif
7205#ifdef O_WRONLY
7206 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7207#endif
7208#ifdef O_RDWR
7209 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7210#endif
7211#ifdef O_NDELAY
7212 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7213#endif
7214#ifdef O_NONBLOCK
7215 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7216#endif
7217#ifdef O_APPEND
7218 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7219#endif
7220#ifdef O_DSYNC
7221 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7222#endif
7223#ifdef O_RSYNC
7224 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7225#endif
7226#ifdef O_SYNC
7227 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7228#endif
7229#ifdef O_NOCTTY
7230 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7231#endif
7232#ifdef O_CREAT
7233 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7234#endif
7235#ifdef O_EXCL
7236 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7237#endif
7238#ifdef O_TRUNC
7239 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7240#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007241#ifdef O_BINARY
7242 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7243#endif
7244#ifdef O_TEXT
7245 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7246#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007247#ifdef O_LARGEFILE
7248 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7249#endif
7250
Tim Peters5aa91602002-01-30 05:46:57 +00007251/* MS Windows */
7252#ifdef O_NOINHERIT
7253 /* Don't inherit in child processes. */
7254 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7255#endif
7256#ifdef _O_SHORT_LIVED
7257 /* Optimize for short life (keep in memory). */
7258 /* MS forgot to define this one with a non-underscore form too. */
7259 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7260#endif
7261#ifdef O_TEMPORARY
7262 /* Automatically delete when last handle is closed. */
7263 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7264#endif
7265#ifdef O_RANDOM
7266 /* Optimize for random access. */
7267 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7268#endif
7269#ifdef O_SEQUENTIAL
7270 /* Optimize for sequential access. */
7271 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7272#endif
7273
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007274/* GNU extensions. */
7275#ifdef O_DIRECT
7276 /* Direct disk access. */
7277 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7278#endif
7279#ifdef O_DIRECTORY
7280 /* Must be a directory. */
7281 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7282#endif
7283#ifdef O_NOFOLLOW
7284 /* Do not follow links. */
7285 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7286#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007287
Guido van Rossum246bc171999-02-01 23:54:31 +00007288#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007289#if defined(PYOS_OS2) && defined(PYCC_GCC)
7290 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7291 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7292 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7293 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7294 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7295 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7296 if (ins(d, "P_PM", (long)P_PM)) return -1;
7297 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7298 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7299 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7300 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7301 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7302 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7303 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7304 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7305 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7306 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7307 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7308 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7309 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7310#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007311 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7312 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7313 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7314 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7315 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007316#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007317#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007318
Guido van Rossumd48f2521997-12-05 22:19:34 +00007319#if defined(PYOS_OS2)
7320 if (insertvalues(d)) return -1;
7321#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007322 return 0;
7323}
7324
7325
Tim Peters5aa91602002-01-30 05:46:57 +00007326#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007327#define INITFUNC initnt
7328#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007329
7330#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007331#define INITFUNC initos2
7332#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007333
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007334#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007335#define INITFUNC initposix
7336#define MODNAME "posix"
7337#endif
7338
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007339PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007340INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007341{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007342 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007343
Fred Drake4d1e64b2002-04-15 19:40:07 +00007344 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007345 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007346 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007347
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007348 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007349 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007350 Py_XINCREF(v);
7351 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007352 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007353 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007354
Fred Drake4d1e64b2002-04-15 19:40:07 +00007355 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007356 return;
7357
Fred Drake4d1e64b2002-04-15 19:40:07 +00007358 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007359 return;
7360
Fred Drake4d1e64b2002-04-15 19:40:07 +00007361 Py_INCREF(PyExc_OSError);
7362 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007363
Guido van Rossumb3d39562000-01-31 18:41:26 +00007364#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007365 if (posix_putenv_garbage == NULL)
7366 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007367#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007368
Guido van Rossum14648392001-12-08 18:02:58 +00007369 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007370 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7371 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7372 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007373 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007374 structseq_new = StatResultType.tp_new;
7375 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007376 Py_INCREF((PyObject*) &StatResultType);
7377 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007378
Guido van Rossum14648392001-12-08 18:02:58 +00007379 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007380 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007381 Py_INCREF((PyObject*) &StatVFSResultType);
7382 PyModule_AddObject(m, "statvfs_result",
7383 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007384}