blob: 37a7d2640880526a87f88cd484a25dbe40c16a79 [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
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000019#if defined(__VMS)
20# include <ctype.h> /* tolower() */
21# include <descrip.h> /* string descriptors */
22# include <dvidef.h> /* DVI$_name */
23# include <file.h> /* -> O_RDWR */
24# include <jpidef.h> /* JPI$_name */
25# include <lib$routines.h> /* LIB$name */
26# include <ots$routines.h> /* OTS$name */
27# include <ssdef.h> /* SS$_name */
28# include <unixio.h>
29# include <unixlib.h>
30# include <stat.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000031# include <wait.h> /* define wait() */
32#endif /* defined(__VMS) */
33
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000035"This module provides access to operating system functionality that is\n\
36standardized by the C Standard and the POSIX standard (a thinly\n\
37disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000038corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000040#ifndef Py_USING_UNICODE
41/* This is used in signatures of functions. */
42#define Py_UNICODE void
43#endif
44
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000045#if defined(PYOS_OS2)
46#define INCL_DOS
47#define INCL_DOSERRORS
48#define INCL_DOSPROCESS
49#define INCL_NOPMAPI
50#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000051#if defined(PYCC_GCC)
52#include <ctype.h>
53#include <io.h>
54#include <stdio.h>
55#include <process.h>
56#include "osdefs.h"
57#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000058#endif
59
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#include <sys/types.h>
61#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000062
Guido van Rossum36bc6801995-06-14 22:54:23 +000063#ifdef HAVE_SYS_WAIT_H
64#include <sys/wait.h> /* For WNOHANG */
65#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000066
Guido van Rossuma376cc51996-12-05 23:43:35 +000067#ifdef HAVE_SIGNAL_H
68#include <signal.h>
69#endif
70
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#ifdef HAVE_FCNTL_H
72#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000073#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000074
Guido van Rossuma6535fd2001-10-18 19:44:10 +000075#ifdef HAVE_GRP_H
76#include <grp.h>
77#endif
78
Barry Warsaw5676bd12003-01-07 20:57:09 +000079#ifdef HAVE_SYSEXITS_H
80#include <sysexits.h>
81#endif /* HAVE_SYSEXITS_H */
82
Guido van Rossuma4916fa1996-05-23 22:58:55 +000083/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000084/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000085#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000086#include <process.h>
87#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000088#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000089#define HAVE_GETCWD 1
90#define HAVE_OPENDIR 1
91#define HAVE_SYSTEM 1
92#if defined(__OS2__)
93#define HAVE_EXECV 1
94#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000095#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000096#include <process.h>
97#else
98#ifdef __BORLANDC__ /* Borland compiler */
99#define HAVE_EXECV 1
100#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_OPENDIR 1
102#define HAVE_PIPE 1
103#define HAVE_POPEN 1
104#define HAVE_SYSTEM 1
105#define HAVE_WAIT 1
106#else
107#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000108#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000109#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000110#define HAVE_EXECV 1
111#define HAVE_PIPE 1
112#define HAVE_POPEN 1
113#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000114#define HAVE_CWAIT 1
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000115#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000116#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
117/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#else /* all other compilers */
119/* Unix functions that the configure script doesn't check for */
120#define HAVE_EXECV 1
121#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000122#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
123#define HAVE_FORK1 1
124#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000125#define HAVE_GETCWD 1
126#define HAVE_GETEGID 1
127#define HAVE_GETEUID 1
128#define HAVE_GETGID 1
129#define HAVE_GETPPID 1
130#define HAVE_GETUID 1
131#define HAVE_KILL 1
132#define HAVE_OPENDIR 1
133#define HAVE_PIPE 1
134#define HAVE_POPEN 1
135#define HAVE_SYSTEM 1
136#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000137#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000138#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#endif /* _MSC_VER */
140#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000141#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000142#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000143
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000144#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000145
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000146#if defined(sun) && !defined(__SVR4)
147/* SunOS 4.1.4 doesn't have prototypes for these: */
148extern int rename(const char *, const char *);
149extern int pclose(FILE *);
150extern int fclose(FILE *);
Thomas Wouters0f954a42001-02-15 08:46:56 +0000151extern int fsync(int);
152extern int lstat(const char *, struct stat *);
153extern int symlink(const char *, const char *);
Guido van Rossumb00adfb2000-09-25 13:22:00 +0000154#endif
155
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000156#if defined(__sgi)&&_COMPILER_VERSION>=700
157/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
158 (default) */
159extern char *ctermid_r(char *);
160#endif
161
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000162#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000163#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000164extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000165#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000166#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000168#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000170#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000171#endif
172#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000173extern int chdir(char *);
174extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int chdir(const char *);
177extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000178#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000179#ifdef __BORLANDC__
180extern int chmod(const char *, int);
181#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000182extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000183#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000184extern int chown(const char *, uid_t, gid_t);
185extern char *getcwd(char *, int);
186extern char *strerror(int);
187extern int link(const char *, const char *);
188extern int rename(const char *, const char *);
189extern int stat(const char *, struct stat *);
190extern int unlink(const char *);
191extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000193extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000194#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000197#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000199
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000200#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_UTIME_H
203#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000204#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000206#ifdef HAVE_SYS_UTIME_H
207#include <sys/utime.h>
208#define HAVE_UTIME_H /* pretend we do for the rest of this file */
209#endif /* HAVE_SYS_UTIME_H */
210
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#ifdef HAVE_SYS_TIMES_H
212#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000213#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214
215#ifdef HAVE_SYS_PARAM_H
216#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000217#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218
219#ifdef HAVE_SYS_UTSNAME_H
220#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000221#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000225#define NAMLEN(dirent) strlen((dirent)->d_name)
226#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000227#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000228#include <direct.h>
229#define NAMLEN(dirent) strlen((dirent)->d_name)
230#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000232#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000233#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000234#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000236#endif
237#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#endif
240#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#endif
243#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000245#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246#include <direct.h>
247#include <io.h>
248#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000249#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000250#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000252#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000253#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000254#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossumd48f2521997-12-05 22:19:34 +0000257#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000259#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260
Tim Petersbc2e10e2002-03-03 23:17:02 +0000261#ifndef MAXPATHLEN
262#define MAXPATHLEN 1024
263#endif /* MAXPATHLEN */
264
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000265#ifdef UNION_WAIT
266/* Emulate some macros on systems that have a union instead of macros */
267
268#ifndef WIFEXITED
269#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
270#endif
271
272#ifndef WEXITSTATUS
273#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
274#endif
275
276#ifndef WTERMSIG
277#define WTERMSIG(u_wait) ((u_wait).w_termsig)
278#endif
279
280#endif /* UNION_WAIT */
281
Greg Wardb48bc172000-03-01 21:51:56 +0000282/* Don't use the "_r" form if we don't need it (also, won't have a
283 prototype for it, at least on Solaris -- maybe others as well?). */
284#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
285#define USE_CTERMID_R
286#endif
287
288#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
289#define USE_TMPNAM_R
290#endif
291
Fred Drake699f3522000-06-29 21:12:41 +0000292/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000293#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000294#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000295# define STAT _stati64
296# define FSTAT _fstati64
297# define STRUCT_STAT struct _stati64
298#else
299# define STAT stat
300# define FSTAT fstat
301# define STRUCT_STAT struct stat
302#endif
303
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000304#if defined(MAJOR_IN_MKDEV)
305#include <sys/mkdev.h>
306#else
307#if defined(MAJOR_IN_SYSMACROS)
308#include <sys/sysmacros.h>
309#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000310#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
311#include <sys/mkdev.h>
312#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000313#endif
Fred Drake699f3522000-06-29 21:12:41 +0000314
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000316#ifdef WITH_NEXT_FRAMEWORK
317/* On Darwin/MacOSX a shared library or framework has no access to
318** environ directly, we must obtain it with _NSGetEnviron().
319*/
320#include <crt_externs.h>
321static char **environ;
322#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000324#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000326#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000327/* add some values to provide a similar environment like POSIX */
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000328static
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000329void
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000330vms_add_posix_env(PyObject *d)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000331{
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000332 PyObject *o;
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000333 char* str;
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000334
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000335 str = getenv("LINES");
336 o = Py_BuildValue("s", str);
337 if (o != NULL) {
338 (void)PyDict_SetItemString(d, "LINES", o);
339 Py_DECREF(o);
340 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000341
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000342 str = getenv("COLUMNS");
343 o = Py_BuildValue("s", str);
344 if (o != NULL) {
345 (void)PyDict_SetItemString(d, "COLUMNS", o);
346 Py_DECREF(o);
347 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000348
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000349 str = getenv("USER");
350 o = Py_BuildValue("s", str);
351 if (o != NULL) {
352 (void)PyDict_SetItemString(d, "USERNAME", o);
353 Py_DECREF(o);
354 }
355 o = Py_BuildValue("s", str);
356 if (o != NULL) {
357 (void)PyDict_SetItemString(d, "LOGNAME", o);
358 Py_DECREF(o);
359 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000360
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000361 str = getenv("HOME");
362 o = Py_BuildValue("s", str);
363 if (o != NULL) {
364 (void)PyDict_SetItemString(d, "HOME", o);
365 Py_DECREF(o);
366 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000367
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000368 str = getenv("PATH");
369 o = Py_BuildValue("s", str);
370 if (o != NULL) {
371 (void)PyDict_SetItemString(d, "PATH", o);
372 Py_DECREF(o);
373 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000374 /* OS = "OpenVMS" */
375 o = PyString_FromString ("OpenVMS");
376 if (o != NULL) {
377 (void)PyDict_SetItemString(d, "OS", o);
378 Py_DECREF(o);
379 }
380}
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000381#endif /* __VMS */
382
Barry Warsaw53699e91996-12-10 23:23:01 +0000383static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000384convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385{
Barry Warsaw53699e91996-12-10 23:23:01 +0000386 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000388 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 if (d == NULL)
390 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000391#ifdef WITH_NEXT_FRAMEWORK
392 if (environ == NULL)
393 environ = *_NSGetEnviron();
394#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395 if (environ == NULL)
396 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000397 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000399 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000400 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401 char *p = strchr(*e, '=');
402 if (p == NULL)
403 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000404 k = PyString_FromStringAndSize(*e, (int)(p-*e));
405 if (k == NULL) {
406 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000408 }
409 v = PyString_FromString(p+1);
410 if (v == NULL) {
411 PyErr_Clear();
412 Py_DECREF(k);
413 continue;
414 }
415 if (PyDict_GetItem(d, k) == NULL) {
416 if (PyDict_SetItem(d, k, v) != 0)
417 PyErr_Clear();
418 }
419 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000420 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421 }
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000422#if defined(__VMS)
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000423 vms_add_posix_env(d);
424#elif defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000425 {
426 APIRET rc;
427 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
428
429 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000430 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000431 PyObject *v = PyString_FromString(buffer);
432 PyDict_SetItemString(d, "BEGINLIBPATH", v);
433 Py_DECREF(v);
434 }
435 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
436 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
437 PyObject *v = PyString_FromString(buffer);
438 PyDict_SetItemString(d, "ENDLIBPATH", v);
439 Py_DECREF(v);
440 }
441 }
442#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000443 return d;
444}
445
446
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000447/* Set a POSIX-specific error from errno, and return NULL */
448
Barry Warsawd58d7641998-07-23 16:14:40 +0000449static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000450posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000451{
Barry Warsawca74da41999-02-09 19:31:45 +0000452 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453}
Barry Warsawd58d7641998-07-23 16:14:40 +0000454static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000455posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000456{
Barry Warsawca74da41999-02-09 19:31:45 +0000457 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000458}
459
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000460#ifdef Py_WIN_WIDE_FILENAMES
461static PyObject *
462posix_error_with_unicode_filename(Py_UNICODE* name)
463{
464 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
465}
466#endif /* Py_WIN_WIDE_FILENAMES */
467
468
Mark Hammondef8b6542001-05-13 08:04:26 +0000469static PyObject *
470posix_error_with_allocated_filename(char* name)
471{
472 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
473 PyMem_Free(name);
474 return rc;
475}
476
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000477#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000478static PyObject *
479win32_error(char* function, char* filename)
480{
Mark Hammond33a6da92000-08-15 00:46:38 +0000481 /* XXX We should pass the function name along in the future.
482 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000483 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000484 Windows error object, which is non-trivial.
485 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000486 errno = GetLastError();
487 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000488 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000489 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000490 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000491}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000492
493#ifdef Py_WIN_WIDE_FILENAMES
494static PyObject *
495win32_error_unicode(char* function, Py_UNICODE* filename)
496{
497 /* XXX - see win32_error for comments on 'function' */
498 errno = GetLastError();
499 if (filename)
500 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
501 else
502 return PyErr_SetFromWindowsErr(errno);
503}
504
505static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
506{
507 /* XXX Perhaps we should make this API an alias of
508 PyObject_Unicode() instead ?! */
509 if (PyUnicode_CheckExact(obj)) {
510 Py_INCREF(obj);
511 return obj;
512 }
513 if (PyUnicode_Check(obj)) {
514 /* For a Unicode subtype that's not a Unicode object,
515 return a true Unicode object with the same data. */
516 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
517 PyUnicode_GET_SIZE(obj));
518 }
519 return PyUnicode_FromEncodedObject(obj,
520 Py_FileSystemDefaultEncoding,
521 "strict");
522}
523
524#endif /* Py_WIN_WIDE_FILENAMES */
525
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000526#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000527
Guido van Rossumd48f2521997-12-05 22:19:34 +0000528#if defined(PYOS_OS2)
529/**********************************************************************
530 * Helper Function to Trim and Format OS/2 Messages
531 **********************************************************************/
532 static void
533os2_formatmsg(char *msgbuf, int msglen, char *reason)
534{
535 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
536
537 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
538 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
539
540 while (lastc > msgbuf && isspace(*lastc))
541 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
542 }
543
544 /* Add Optional Reason Text */
545 if (reason) {
546 strcat(msgbuf, " : ");
547 strcat(msgbuf, reason);
548 }
549}
550
551/**********************************************************************
552 * Decode an OS/2 Operating System Error Code
553 *
554 * A convenience function to lookup an OS/2 error code and return a
555 * text message we can use to raise a Python exception.
556 *
557 * Notes:
558 * The messages for errors returned from the OS/2 kernel reside in
559 * the file OSO001.MSG in the \OS2 directory hierarchy.
560 *
561 **********************************************************************/
562 static char *
563os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
564{
565 APIRET rc;
566 ULONG msglen;
567
568 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
569 Py_BEGIN_ALLOW_THREADS
570 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
571 errorcode, "oso001.msg", &msglen);
572 Py_END_ALLOW_THREADS
573
574 if (rc == NO_ERROR)
575 os2_formatmsg(msgbuf, msglen, reason);
576 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000577 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000578 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000579
580 return msgbuf;
581}
582
583/* Set an OS/2-specific error and return NULL. OS/2 kernel
584 errors are not in a global variable e.g. 'errno' nor are
585 they congruent with posix error numbers. */
586
587static PyObject * os2_error(int code)
588{
589 char text[1024];
590 PyObject *v;
591
592 os2_strerror(text, sizeof(text), code, "");
593
594 v = Py_BuildValue("(is)", code, text);
595 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000596 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000597 Py_DECREF(v);
598 }
599 return NULL; /* Signal to Python that an Exception is Pending */
600}
601
602#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603
604/* POSIX generic methods */
605
Barry Warsaw53699e91996-12-10 23:23:01 +0000606static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000607posix_fildes(PyObject *fdobj, int (*func)(int))
608{
609 int fd;
610 int res;
611 fd = PyObject_AsFileDescriptor(fdobj);
612 if (fd < 0)
613 return NULL;
614 Py_BEGIN_ALLOW_THREADS
615 res = (*func)(fd);
616 Py_END_ALLOW_THREADS
617 if (res < 0)
618 return posix_error();
619 Py_INCREF(Py_None);
620 return Py_None;
621}
Guido van Rossum21142a01999-01-08 21:05:37 +0000622
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000623#ifdef Py_WIN_WIDE_FILENAMES
624static int
625unicode_file_names(void)
626{
627 static int canusewide = -1;
628 if (canusewide == -1) {
629 /* As per doc for ::GetVersion(), this is the correct test for
630 the Windows NT family. */
631 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
632 }
633 return canusewide;
634}
635#endif
636
Guido van Rossum21142a01999-01-08 21:05:37 +0000637static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000638posix_1str(PyObject *args, char *format, int (*func)(const char*),
639 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000640{
Mark Hammondef8b6542001-05-13 08:04:26 +0000641 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000642 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000643#ifdef Py_WIN_WIDE_FILENAMES
644 if (unicode_file_names()) {
645 PyUnicodeObject *po;
646 if (PyArg_ParseTuple(args, wformat, &po)) {
647 Py_BEGIN_ALLOW_THREADS
648 /* PyUnicode_AS_UNICODE OK without thread
649 lock as it is a simple dereference. */
650 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
651 Py_END_ALLOW_THREADS
652 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000653 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000654 Py_INCREF(Py_None);
655 return Py_None;
656 }
657 /* Drop the argument parsing error as narrow
658 strings are also valid. */
659 PyErr_Clear();
660 }
661#else
662 /* Platforms that don't support Unicode filenames
663 shouldn't be passing these extra params */
664 assert(wformat==NULL && wfunc == NULL);
665#endif
666
Tim Peters5aa91602002-01-30 05:46:57 +0000667 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000668 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000669 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000670 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000671 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000672 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000673 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000674 return posix_error_with_allocated_filename(path1);
675 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000676 Py_INCREF(Py_None);
677 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000678}
679
Barry Warsaw53699e91996-12-10 23:23:01 +0000680static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000681posix_2str(PyObject *args,
682 char *format,
683 int (*func)(const char *, const char *),
684 char *wformat,
685 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000686{
Mark Hammondef8b6542001-05-13 08:04:26 +0000687 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000688 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000689#ifdef Py_WIN_WIDE_FILENAMES
690 if (unicode_file_names()) {
691 PyObject *po1;
692 PyObject *po2;
693 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
694 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
695 PyObject *wpath1;
696 PyObject *wpath2;
697 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
698 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
699 if (!wpath1 || !wpath2) {
700 Py_XDECREF(wpath1);
701 Py_XDECREF(wpath2);
702 return NULL;
703 }
704 Py_BEGIN_ALLOW_THREADS
705 /* PyUnicode_AS_UNICODE OK without thread
706 lock as it is a simple dereference. */
707 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
708 PyUnicode_AS_UNICODE(wpath2));
709 Py_END_ALLOW_THREADS
710 Py_XDECREF(wpath1);
711 Py_XDECREF(wpath2);
712 if (res != 0)
713 return posix_error();
714 Py_INCREF(Py_None);
715 return Py_None;
716 }
717 /* Else flow through as neither is Unicode. */
718 }
719 /* Drop the argument parsing error as narrow
720 strings are also valid. */
721 PyErr_Clear();
722 }
723#else
724 /* Platforms that don't support Unicode filenames
725 shouldn't be passing these extra params */
726 assert(wformat==NULL && wfunc == NULL);
727#endif
728
Mark Hammondef8b6542001-05-13 08:04:26 +0000729 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000730 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000731 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000732 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000733 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000734 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000735 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000736 PyMem_Free(path1);
737 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000738 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000739 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000740 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000741 Py_INCREF(Py_None);
742 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000743}
744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000745PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000746"stat_result: Result from stat or lstat.\n\n\
747This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000748 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000749or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
750\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000751Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000752they are available as attributes only.\n\
753\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000754See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000755
756static PyStructSequence_Field stat_result_fields[] = {
757 {"st_mode", "protection bits"},
758 {"st_ino", "inode"},
759 {"st_dev", "device"},
760 {"st_nlink", "number of hard links"},
761 {"st_uid", "user ID of owner"},
762 {"st_gid", "group ID of owner"},
763 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000764 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
765 {NULL, "integer time of last access"},
766 {NULL, "integer time of last modification"},
767 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000768 {"st_atime", "time of last access"},
769 {"st_mtime", "time of last modification"},
770 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000771#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000772 {"st_blksize", "blocksize for filesystem I/O"},
773#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000774#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000775 {"st_blocks", "number of blocks allocated"},
776#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000777#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000778 {"st_rdev", "device type (if inode device)"},
779#endif
780 {0}
781};
782
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000783#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000784#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000785#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000786#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000787#endif
788
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000789#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000790#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
791#else
792#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
793#endif
794
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000795#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000796#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
797#else
798#define ST_RDEV_IDX ST_BLOCKS_IDX
799#endif
800
801static PyStructSequence_Desc stat_result_desc = {
802 "stat_result", /* name */
803 stat_result__doc__, /* doc */
804 stat_result_fields,
805 10
806};
807
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000808PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000809"statvfs_result: Result from statvfs or fstatvfs.\n\n\
810This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000811 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000812or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000813\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000814See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000815
816static PyStructSequence_Field statvfs_result_fields[] = {
817 {"f_bsize", },
818 {"f_frsize", },
819 {"f_blocks", },
820 {"f_bfree", },
821 {"f_bavail", },
822 {"f_files", },
823 {"f_ffree", },
824 {"f_favail", },
825 {"f_flag", },
826 {"f_namemax",},
827 {0}
828};
829
830static PyStructSequence_Desc statvfs_result_desc = {
831 "statvfs_result", /* name */
832 statvfs_result__doc__, /* doc */
833 statvfs_result_fields,
834 10
835};
836
837static PyTypeObject StatResultType;
838static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000839static newfunc structseq_new;
840
841static PyObject *
842statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
843{
844 PyStructSequence *result;
845 int i;
846
847 result = (PyStructSequence*)structseq_new(type, args, kwds);
848 if (!result)
849 return NULL;
850 /* If we have been initialized from a tuple,
851 st_?time might be set to None. Initialize it
852 from the int slots. */
853 for (i = 7; i <= 9; i++) {
854 if (result->ob_item[i+3] == Py_None) {
855 Py_DECREF(Py_None);
856 Py_INCREF(result->ob_item[i]);
857 result->ob_item[i+3] = result->ob_item[i];
858 }
859 }
860 return (PyObject*)result;
861}
862
863
864
865/* If true, st_?time is float. */
866static int _stat_float_times = 0;
867
868PyDoc_STRVAR(stat_float_times__doc__,
869"stat_float_times([newval]) -> oldval\n\n\
870Determine whether os.[lf]stat represents time stamps as float objects.\n\
871If newval is True, future calls to stat() return floats, if it is False,\n\
872future calls return ints. \n\
873If newval is omitted, return the current setting.\n");
874
875static PyObject*
876stat_float_times(PyObject* self, PyObject *args)
877{
878 int newval = -1;
879 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
880 return NULL;
881 if (newval == -1)
882 /* Return old value */
883 return PyBool_FromLong(_stat_float_times);
884 _stat_float_times = newval;
885 Py_INCREF(Py_None);
886 return Py_None;
887}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000888
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000889static void
890fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
891{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000892 PyObject *fval,*ival;
893#if SIZEOF_TIME_T > SIZEOF_LONG
894 ival = PyLong_FromLongLong((LONG_LONG)sec);
895#else
896 ival = PyInt_FromLong((long)sec);
897#endif
898 if (_stat_float_times) {
899 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
900 } else {
901 fval = ival;
902 Py_INCREF(fval);
903 }
904 PyStructSequence_SET_ITEM(v, index, ival);
905 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000906}
907
Tim Peters5aa91602002-01-30 05:46:57 +0000908/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000909 (used by posix_stat() and posix_fstat()) */
910static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000911_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000912{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000913 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000914 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000915 if (v == NULL)
916 return NULL;
917
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000918 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000919#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000920 PyStructSequence_SET_ITEM(v, 1,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000921 PyLong_FromLongLong((LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000922#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000923 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000924#endif
925#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000926 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000927 PyLong_FromLongLong((LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000928#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000929 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000930#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000931 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
932 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
933 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000934#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000935 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000936 PyLong_FromLongLong((LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000937#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000938 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000939#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000940
941#ifdef HAVE_STAT_TV_NSEC
942 ansec = st.st_atim.tv_nsec;
943 mnsec = st.st_mtim.tv_nsec;
944 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000945#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000946 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000947#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000948 fill_time(v, 7, st.st_atime, ansec);
949 fill_time(v, 8, st.st_mtime, mnsec);
950 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000951
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000952#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000953 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000954 PyInt_FromLong((long)st.st_blksize));
955#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000956#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000957 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000958 PyInt_FromLong((long)st.st_blocks));
959#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000960#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000961 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
962 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000963#endif
964
965 if (PyErr_Occurred()) {
966 Py_DECREF(v);
967 return NULL;
968 }
969
970 return v;
971}
972
Barry Warsaw53699e91996-12-10 23:23:01 +0000973static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000974posix_do_stat(PyObject *self, PyObject *args,
975 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000976#ifdef __VMS
977 int (*statfunc)(const char *, STRUCT_STAT *, ...),
978#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000979 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000980#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000981 char *wformat,
982 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000983{
Fred Drake699f3522000-06-29 21:12:41 +0000984 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000985 char *path = NULL; /* pass this to stat; do not free() it */
986 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000987 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000988
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000989#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000990 int pathlen;
991 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000992#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000993
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000994
995#ifdef Py_WIN_WIDE_FILENAMES
996 /* If on wide-character-capable OS see if argument
997 is Unicode and if so use wide API. */
998 if (unicode_file_names()) {
999 PyUnicodeObject *po;
1000 if (PyArg_ParseTuple(args, wformat, &po)) {
1001 Py_UNICODE wpath[MAX_PATH+1];
1002 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
1003 /* the library call can blow up if the file name is too long! */
1004 if (pathlen > MAX_PATH) {
1005 errno = ENAMETOOLONG;
1006 return posix_error();
1007 }
1008 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
1009 /* Remove trailing slash or backslash, unless it's the current
1010 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1011 */
1012 if (pathlen > 0 &&
1013 (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) {
1014 /* It does end with a slash -- exempt the root drive cases. */
1015 /* XXX UNC root drives should also be exempted? */
1016 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':'))
1017 /* leave it alone */;
1018 else {
1019 /* nuke the trailing backslash */
1020 wpath[pathlen-1] = L'\0';
1021 }
1022 }
1023 Py_BEGIN_ALLOW_THREADS
1024 /* PyUnicode_AS_UNICODE result OK without
1025 thread lock as it is a simple dereference. */
1026 res = wstatfunc(wpath, &st);
1027 Py_END_ALLOW_THREADS
1028 if (res != 0)
1029 return posix_error_with_unicode_filename(wpath);
1030 return _pystat_fromstructstat(st);
1031 }
1032 /* Drop the argument parsing error as narrow strings
1033 are also valid. */
1034 PyErr_Clear();
1035 }
1036#endif
1037
Tim Peters5aa91602002-01-30 05:46:57 +00001038 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001039 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001040 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001041 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001042
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001043#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +00001044 pathlen = strlen(path);
1045 /* the library call can blow up if the file name is too long! */
1046 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +00001047 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +00001048 errno = ENAMETOOLONG;
1049 return posix_error();
1050 }
1051
Tim Peters500bd032001-12-19 19:05:01 +00001052 /* Remove trailing slash or backslash, unless it's the current
1053 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1054 */
1055 if (pathlen > 0 &&
1056 (path[pathlen-1]== '\\' || path[pathlen-1] == '/')) {
1057 /* It does end with a slash -- exempt the root drive cases. */
1058 /* XXX UNC root drives should also be exempted? */
1059 if (pathlen == 1 || (pathlen == 3 && path[1] == ':'))
1060 /* leave it alone */;
1061 else {
1062 /* nuke the trailing backslash */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001063 strncpy(pathcopy, path, pathlen);
Tim Peters500bd032001-12-19 19:05:01 +00001064 pathcopy[pathlen-1] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +00001065 path = pathcopy;
1066 }
1067 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001068#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001069
Barry Warsaw53699e91996-12-10 23:23:01 +00001070 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001071 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001072 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001073 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001074 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001075
Tim Peters500bd032001-12-19 19:05:01 +00001076 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001077 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001078}
1079
1080
1081/* POSIX methods */
1082
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001083PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001084"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001085Use the real uid/gid to test for access to a path. Note that most\n\
1086operations will use the effective uid/gid, therefore this routine can\n\
1087be used in a suid/sgid environment to test if the invoking user has the\n\
1088specified access to the path. The mode argument can be F_OK to test\n\
1089existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001090
1091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001092posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001093{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001094 char *path;
1095 int mode;
1096 int res;
1097
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001098 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001099 return NULL;
1100 Py_BEGIN_ALLOW_THREADS
1101 res = access(path, mode);
1102 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001103 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001104}
1105
Guido van Rossumd371ff11999-01-25 16:12:23 +00001106#ifndef F_OK
1107#define F_OK 0
1108#endif
1109#ifndef R_OK
1110#define R_OK 4
1111#endif
1112#ifndef W_OK
1113#define W_OK 2
1114#endif
1115#ifndef X_OK
1116#define X_OK 1
1117#endif
1118
1119#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001120PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001121"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001122Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001123
1124static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001125posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001126{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001127 int id;
1128 char *ret;
1129
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001130 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001131 return NULL;
1132
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001133#if defined(__VMS)
1134 /* DECC V5.0 - only about FD= 0 @@ try getname()+$getdvi(dvi$_devnam) */
1135 if (id == 0) {
1136 ret = ttyname();
1137 }
1138 else {
1139 ret = NULL;
1140 }
1141#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001142 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001143#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001144 if (ret == NULL)
1145 return(posix_error());
1146 return(PyString_FromString(ret));
1147}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001148#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001149
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001150#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001151PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001152"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001153Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001154
1155static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001156posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001157{
1158 char *ret;
1159 char buffer[L_ctermid];
1160
Greg Wardb48bc172000-03-01 21:51:56 +00001161#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001162 ret = ctermid_r(buffer);
1163#else
1164 ret = ctermid(buffer);
1165#endif
1166 if (ret == NULL)
1167 return(posix_error());
1168 return(PyString_FromString(buffer));
1169}
1170#endif
1171
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001172PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001173"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001174Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001175
Barry Warsaw53699e91996-12-10 23:23:01 +00001176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001177posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001178{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001179#ifdef MS_WINDOWS
1180 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1181#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1182 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001183#elif defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001184 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
1185 NULL, NULL);
1186#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001187 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001188#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001189}
1190
Fred Drake4d1e64b2002-04-15 19:40:07 +00001191#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001192PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001193"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001194Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001195opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001196
1197static PyObject *
1198posix_fchdir(PyObject *self, PyObject *fdobj)
1199{
1200 return posix_fildes(fdobj, fchdir);
1201}
1202#endif /* HAVE_FCHDIR */
1203
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001204
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001205PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001206"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001207Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001208
Barry Warsaw53699e91996-12-10 23:23:01 +00001209static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001210posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211{
Mark Hammondef8b6542001-05-13 08:04:26 +00001212 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001213 int i;
1214 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001215 if (!PyArg_ParseTuple(args, "eti", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001216 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001217 return NULL;
1218 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001219 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001220 Py_END_ALLOW_THREADS
1221 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001222 return posix_error_with_allocated_filename(path);
1223 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001224 Py_INCREF(Py_None);
1225 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226}
1227
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001228
Martin v. Löwis244edc82001-10-04 22:44:26 +00001229#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001230PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001231"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001232Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001233
1234static PyObject *
1235posix_chroot(PyObject *self, PyObject *args)
1236{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001237 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001238}
1239#endif
1240
Guido van Rossum21142a01999-01-08 21:05:37 +00001241#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001242PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001243"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001244force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001245
1246static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001247posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001248{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001249 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001250}
1251#endif /* HAVE_FSYNC */
1252
1253#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001254
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001255#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001256extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1257#endif
1258
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001259PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001260"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001261force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001262 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001263
1264static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001265posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001266{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001267 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001268}
1269#endif /* HAVE_FDATASYNC */
1270
1271
Fredrik Lundh10723342000-07-10 16:38:09 +00001272#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001273PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001274"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001275Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001276
Barry Warsaw53699e91996-12-10 23:23:01 +00001277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001278posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001279{
Mark Hammondef8b6542001-05-13 08:04:26 +00001280 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001281 int uid, gid;
1282 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001283 if (!PyArg_ParseTuple(args, "etii:chown",
1284 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001285 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001286 return NULL;
1287 Py_BEGIN_ALLOW_THREADS
1288 res = chown(path, (uid_t) uid, (gid_t) gid);
1289 Py_END_ALLOW_THREADS
1290 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001291 return posix_error_with_allocated_filename(path);
1292 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001293 Py_INCREF(Py_None);
1294 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001295}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001296#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001297
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001298#ifdef HAVE_LCHOWN
1299PyDoc_STRVAR(posix_lchown__doc__,
1300"lchown(path, uid, gid)\n\n\
1301Change the owner and group id of path to the numeric uid and gid.\n\
1302This function will not follow symbolic links.");
1303
1304static PyObject *
1305posix_lchown(PyObject *self, PyObject *args)
1306{
1307 char *path = NULL;
1308 int uid, gid;
1309 int res;
1310 if (!PyArg_ParseTuple(args, "etii:lchown",
1311 Py_FileSystemDefaultEncoding, &path,
1312 &uid, &gid))
1313 return NULL;
1314 Py_BEGIN_ALLOW_THREADS
1315 res = lchown(path, (uid_t) uid, (gid_t) gid);
1316 Py_END_ALLOW_THREADS
Neal Norwitze241ce82003-02-17 18:17:05 +00001317 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001318 return posix_error_with_allocated_filename(path);
1319 PyMem_Free(path);
1320 Py_INCREF(Py_None);
1321 return Py_None;
1322}
1323#endif /* HAVE_LCHOWN */
1324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001325
Guido van Rossum36bc6801995-06-14 22:54:23 +00001326#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001327PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001328"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001329Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001330
Barry Warsaw53699e91996-12-10 23:23:01 +00001331static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001332posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333{
1334 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001335 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001336
Barry Warsaw53699e91996-12-10 23:23:01 +00001337 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001338#if defined(PYOS_OS2) && defined(PYCC_GCC)
1339 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001340#elif defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001341 /* 0 = force Unix-style path if in the VMS DCL environment! */
1342 res = getcwd(buf, sizeof buf, 0);
1343#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001344 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001345#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001346 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001347 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001349 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001350}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001351
Walter Dörwald3b918c32002-11-21 20:18:46 +00001352#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001353PyDoc_STRVAR(posix_getcwdu__doc__,
1354"getcwdu() -> path\n\n\
1355Return a unicode string representing the current working directory.");
1356
1357static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001358posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001359{
1360 char buf[1026];
1361 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001362
1363#ifdef Py_WIN_WIDE_FILENAMES
1364 if (unicode_file_names()) {
1365 wchar_t *wres;
1366 wchar_t wbuf[1026];
1367 Py_BEGIN_ALLOW_THREADS
1368 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1369 Py_END_ALLOW_THREADS
1370 if (wres == NULL)
1371 return posix_error();
1372 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1373 }
1374#endif
1375
1376 Py_BEGIN_ALLOW_THREADS
1377#if defined(PYOS_OS2) && defined(PYCC_GCC)
1378 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001379#elif defined(__VMS)
1380 /* 0 = force Unix-style path if in the VMS DCL environment! */
1381 res = getcwd(buf, sizeof buf, 0);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001382#else
1383 res = getcwd(buf, sizeof buf);
1384#endif
1385 Py_END_ALLOW_THREADS
1386 if (res == NULL)
1387 return posix_error();
1388 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1389}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001390#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001391#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001393
Guido van Rossumb6775db1994-08-01 11:34:53 +00001394#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001395PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001396"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001397Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001398
Barry Warsaw53699e91996-12-10 23:23:01 +00001399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001400posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001401{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001402 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001403}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001404#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001405
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001406
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001407PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001408"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001409Return a list containing the names of the entries in the directory.\n\
1410\n\
1411 path: path of directory to list\n\
1412\n\
1413The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001414entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001415
Barry Warsaw53699e91996-12-10 23:23:01 +00001416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001417posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001418{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001419 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001420 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001421#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001422
Barry Warsaw53699e91996-12-10 23:23:01 +00001423 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001424 HANDLE hFindFile;
1425 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001426 /* MAX_PATH characters could mean a bigger encoded string */
1427 char namebuf[MAX_PATH*2+5];
1428 char *bufptr = namebuf;
1429 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001430
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001431#ifdef Py_WIN_WIDE_FILENAMES
1432 /* If on wide-character-capable OS see if argument
1433 is Unicode and if so use wide API. */
1434 if (unicode_file_names()) {
1435 PyUnicodeObject *po;
1436 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1437 WIN32_FIND_DATAW wFileData;
1438 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1439 Py_UNICODE wch;
1440 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1441 wnamebuf[MAX_PATH] = L'\0';
1442 len = wcslen(wnamebuf);
1443 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1444 if (wch != L'/' && wch != L'\\' && wch != L':')
1445 wnamebuf[len++] = L'/';
1446 wcscpy(wnamebuf + len, L"*.*");
1447 if ((d = PyList_New(0)) == NULL)
1448 return NULL;
1449 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1450 if (hFindFile == INVALID_HANDLE_VALUE) {
1451 errno = GetLastError();
1452 if (errno == ERROR_FILE_NOT_FOUND) {
1453 return d;
1454 }
1455 Py_DECREF(d);
1456 return win32_error_unicode("FindFirstFileW", wnamebuf);
1457 }
1458 do {
1459 if (wFileData.cFileName[0] == L'.' &&
1460 (wFileData.cFileName[1] == L'\0' ||
1461 wFileData.cFileName[1] == L'.' &&
1462 wFileData.cFileName[2] == L'\0'))
1463 continue;
1464 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1465 if (v == NULL) {
1466 Py_DECREF(d);
1467 d = NULL;
1468 break;
1469 }
1470 if (PyList_Append(d, v) != 0) {
1471 Py_DECREF(v);
1472 Py_DECREF(d);
1473 d = NULL;
1474 break;
1475 }
1476 Py_DECREF(v);
1477 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1478
1479 if (FindClose(hFindFile) == FALSE) {
1480 Py_DECREF(d);
1481 return win32_error_unicode("FindClose", wnamebuf);
1482 }
1483 return d;
1484 }
1485 /* Drop the argument parsing error as narrow strings
1486 are also valid. */
1487 PyErr_Clear();
1488 }
1489#endif
1490
Tim Peters5aa91602002-01-30 05:46:57 +00001491 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001492 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001493 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001494 if (len > 0) {
1495 char ch = namebuf[len-1];
1496 if (ch != SEP && ch != ALTSEP && ch != ':')
1497 namebuf[len++] = '/';
1498 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001499 strcpy(namebuf + len, "*.*");
1500
Barry Warsaw53699e91996-12-10 23:23:01 +00001501 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001502 return NULL;
1503
1504 hFindFile = FindFirstFile(namebuf, &FileData);
1505 if (hFindFile == INVALID_HANDLE_VALUE) {
1506 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001507 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001508 return d;
1509 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001510 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001511 }
1512 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001513 if (FileData.cFileName[0] == '.' &&
1514 (FileData.cFileName[1] == '\0' ||
1515 FileData.cFileName[1] == '.' &&
1516 FileData.cFileName[2] == '\0'))
1517 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001518 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001519 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001520 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001521 d = NULL;
1522 break;
1523 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001524 if (PyList_Append(d, v) != 0) {
1525 Py_DECREF(v);
1526 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001527 d = NULL;
1528 break;
1529 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001530 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001531 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1532
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001533 if (FindClose(hFindFile) == FALSE) {
1534 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001535 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001536 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001537
1538 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001539
Tim Peters0bb44a42000-09-15 07:44:49 +00001540#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001541
1542#ifndef MAX_PATH
1543#define MAX_PATH CCHMAXPATH
1544#endif
1545 char *name, *pt;
1546 int len;
1547 PyObject *d, *v;
1548 char namebuf[MAX_PATH+5];
1549 HDIR hdir = 1;
1550 ULONG srchcnt = 1;
1551 FILEFINDBUF3 ep;
1552 APIRET rc;
1553
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001554 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001555 return NULL;
1556 if (len >= MAX_PATH) {
1557 PyErr_SetString(PyExc_ValueError, "path too long");
1558 return NULL;
1559 }
1560 strcpy(namebuf, name);
1561 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001562 if (*pt == ALTSEP)
1563 *pt = SEP;
1564 if (namebuf[len-1] != SEP)
1565 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001566 strcpy(namebuf + len, "*.*");
1567
1568 if ((d = PyList_New(0)) == NULL)
1569 return NULL;
1570
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001571 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1572 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001573 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001574 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1575 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1576 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001577
1578 if (rc != NO_ERROR) {
1579 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001580 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001581 }
1582
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001583 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001584 do {
1585 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001586 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001587 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001588
1589 strcpy(namebuf, ep.achName);
1590
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001591 /* Leave Case of Name Alone -- In Native Form */
1592 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001593
1594 v = PyString_FromString(namebuf);
1595 if (v == NULL) {
1596 Py_DECREF(d);
1597 d = NULL;
1598 break;
1599 }
1600 if (PyList_Append(d, v) != 0) {
1601 Py_DECREF(v);
1602 Py_DECREF(d);
1603 d = NULL;
1604 break;
1605 }
1606 Py_DECREF(v);
1607 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1608 }
1609
1610 return d;
1611#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001612
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001613 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001614 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001615 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001616 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001617 int arg_is_unicode = 1;
1618
1619 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1620 arg_is_unicode = 0;
1621 PyErr_Clear();
1622 }
1623 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001624 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001625 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001626 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001627 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001628 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001629 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001630 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001631 return NULL;
1632 }
1633 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001634 if (ep->d_name[0] == '.' &&
1635 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001636 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001637 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001638 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001639 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001640 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641 d = NULL;
1642 break;
1643 }
Just van Rossum46c97842003-02-25 21:42:15 +00001644#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001645 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001646 PyObject *w;
1647
1648 w = PyUnicode_FromEncodedObject(v,
1649 Py_FileSystemDefaultEncoding,
1650 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001651 if (w != NULL) {
1652 Py_DECREF(v);
1653 v = w;
1654 }
1655 else {
1656 /* fall back to the original byte string, as
1657 discussed in patch #683592 */
1658 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001659 }
Just van Rossum46c97842003-02-25 21:42:15 +00001660 }
1661#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001662 if (PyList_Append(d, v) != 0) {
1663 Py_DECREF(v);
1664 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001665 d = NULL;
1666 break;
1667 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001668 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001669 }
1670 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001671 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001672
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001673 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001674
Tim Peters0bb44a42000-09-15 07:44:49 +00001675#endif /* which OS */
1676} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001677
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001678#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001679/* A helper function for abspath on win32 */
1680static PyObject *
1681posix__getfullpathname(PyObject *self, PyObject *args)
1682{
1683 /* assume encoded strings wont more than double no of chars */
1684 char inbuf[MAX_PATH*2];
1685 char *inbufp = inbuf;
1686 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1687 char outbuf[MAX_PATH*2];
1688 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001689#ifdef Py_WIN_WIDE_FILENAMES
1690 if (unicode_file_names()) {
1691 PyUnicodeObject *po;
1692 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1693 Py_UNICODE woutbuf[MAX_PATH*2];
1694 Py_UNICODE *wtemp;
1695 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1696 sizeof(woutbuf)/sizeof(woutbuf[0]),
1697 woutbuf, &wtemp))
1698 return win32_error("GetFullPathName", "");
1699 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1700 }
1701 /* Drop the argument parsing error as narrow strings
1702 are also valid. */
1703 PyErr_Clear();
1704 }
1705#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001706 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1707 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001708 &insize))
1709 return NULL;
1710 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1711 outbuf, &temp))
1712 return win32_error("GetFullPathName", inbuf);
1713 return PyString_FromString(outbuf);
1714} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001715#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001717PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001718"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001719Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001720
Barry Warsaw53699e91996-12-10 23:23:01 +00001721static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001722posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001723{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001724 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001725 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001726 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001727
1728#ifdef Py_WIN_WIDE_FILENAMES
1729 if (unicode_file_names()) {
1730 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001731 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001732 Py_BEGIN_ALLOW_THREADS
1733 /* PyUnicode_AS_UNICODE OK without thread lock as
1734 it is a simple dereference. */
1735 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1736 Py_END_ALLOW_THREADS
1737 if (res < 0)
1738 return posix_error();
1739 Py_INCREF(Py_None);
1740 return Py_None;
1741 }
1742 /* Drop the argument parsing error as narrow strings
1743 are also valid. */
1744 PyErr_Clear();
1745 }
1746#endif
1747
Tim Peters5aa91602002-01-30 05:46:57 +00001748 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001749 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001750 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001751 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001752#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001753 res = mkdir(path);
1754#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001755 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001756#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001757 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001758 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001759 return posix_error_with_allocated_filename(path);
1760 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001761 Py_INCREF(Py_None);
1762 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001763}
1764
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001765
Guido van Rossumb6775db1994-08-01 11:34:53 +00001766#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001767#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1768#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1769#include <sys/resource.h>
1770#endif
1771#endif
1772
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001774"nice(inc) -> new_priority\n\n\
1775Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001776
Barry Warsaw53699e91996-12-10 23:23:01 +00001777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001778posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001779{
1780 int increment, value;
1781
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001782 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001783 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001784
1785 /* There are two flavours of 'nice': one that returns the new
1786 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001787 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1788 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001789
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001790 If we are of the nice family that returns the new priority, we
1791 need to clear errno before the call, and check if errno is filled
1792 before calling posix_error() on a returnvalue of -1, because the
1793 -1 may be the actual new priority! */
1794
1795 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001796 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001797#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001798 if (value == 0)
1799 value = getpriority(PRIO_PROCESS, 0);
1800#endif
1801 if (value == -1 && errno != 0)
1802 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001803 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001804 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001805}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001806#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001807
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001808
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001809PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001810"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001811Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001812
Barry Warsaw53699e91996-12-10 23:23:01 +00001813static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001814posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001815{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001816#ifdef MS_WINDOWS
1817 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1818#else
1819 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1820#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001821}
1822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001823
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001824PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001825"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001826Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001827
Barry Warsaw53699e91996-12-10 23:23:01 +00001828static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001829posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001830{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001831#ifdef MS_WINDOWS
1832 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1833#else
1834 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1835#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001836}
1837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001840"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001841Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001842
Barry Warsaw53699e91996-12-10 23:23:01 +00001843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001844posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001845{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001846#ifdef MS_WINDOWS
1847 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1848#else
1849 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1850#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001851}
1852
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001853
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001854#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001855PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001856"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001858
Barry Warsaw53699e91996-12-10 23:23:01 +00001859static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001860posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001861{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001862 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001863 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001864 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001865 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001866 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001867 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001868 Py_END_ALLOW_THREADS
1869 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001870}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001871#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001872
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001873
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001874PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001875"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001876Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001877
Barry Warsaw53699e91996-12-10 23:23:01 +00001878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001879posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001880{
1881 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001882 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001883 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001884 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001885 if (i < 0)
1886 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001887 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001888}
1889
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001890
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001891PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001892"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001893Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001894
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001895PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001896"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001897Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001898
Barry Warsaw53699e91996-12-10 23:23:01 +00001899static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001900posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001901{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001902#ifdef MS_WINDOWS
1903 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1904#else
1905 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1906#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001907}
1908
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001909
Guido van Rossumb6775db1994-08-01 11:34:53 +00001910#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001911PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001912"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001913Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001914
Barry Warsaw53699e91996-12-10 23:23:01 +00001915static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001916posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001917{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001918 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001919 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001920
Barry Warsaw53699e91996-12-10 23:23:01 +00001921 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001922 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001923 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001924 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001925 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001926 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001927 u.sysname,
1928 u.nodename,
1929 u.release,
1930 u.version,
1931 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001932}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001933#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001934
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001935static int
1936extract_time(PyObject *t, long* sec, long* usec)
1937{
1938 long intval;
1939 if (PyFloat_Check(t)) {
1940 double tval = PyFloat_AsDouble(t);
1941 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1942 if (!intobj)
1943 return -1;
1944 intval = PyInt_AsLong(intobj);
1945 Py_DECREF(intobj);
1946 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001947 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001948 if (*usec < 0)
1949 /* If rounding gave us a negative number,
1950 truncate. */
1951 *usec = 0;
1952 return 0;
1953 }
1954 intval = PyInt_AsLong(t);
1955 if (intval == -1 && PyErr_Occurred())
1956 return -1;
1957 *sec = intval;
1958 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001959 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001960}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001961
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001962PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001963"utime(path, (atime, utime))\n\
1964utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001965Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001966second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001967
Barry Warsaw53699e91996-12-10 23:23:01 +00001968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001969posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001970{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001971 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001972 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001973 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001974 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001975
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001976#if defined(HAVE_UTIMES)
1977 struct timeval buf[2];
1978#define ATIME buf[0].tv_sec
1979#define MTIME buf[1].tv_sec
1980#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001981/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001982 struct utimbuf buf;
1983#define ATIME buf.actime
1984#define MTIME buf.modtime
1985#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001986#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001987 time_t buf[2];
1988#define ATIME buf[0]
1989#define MTIME buf[1]
1990#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001991#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001992
Barry Warsaw3cef8562000-05-01 16:17:24 +00001993 if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001994 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00001995 if (arg == Py_None) {
1996 /* optional time values not given */
1997 Py_BEGIN_ALLOW_THREADS
1998 res = utime(path, NULL);
1999 Py_END_ALLOW_THREADS
2000 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002001 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002002 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002003 "utime() arg 2 must be a tuple (atime, mtime)");
Barry Warsaw3cef8562000-05-01 16:17:24 +00002004 return NULL;
2005 }
2006 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002007 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2008 &atime, &ausec) == -1)
2009 return NULL;
2010 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2011 &mtime, &musec) == -1)
2012 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002013 ATIME = atime;
2014 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002015#ifdef HAVE_UTIMES
2016 buf[0].tv_usec = ausec;
2017 buf[1].tv_usec = musec;
2018 Py_BEGIN_ALLOW_THREADS
2019 res = utimes(path, buf);
2020 Py_END_ALLOW_THREADS
2021#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002022 Py_BEGIN_ALLOW_THREADS
2023 res = utime(path, UTIME_ARG);
2024 Py_END_ALLOW_THREADS
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002025#endif
Barry Warsaw3cef8562000-05-01 16:17:24 +00002026 }
Guido van Rossumff4949e1992-08-05 19:58:53 +00002027 if (res < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00002028 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002029 Py_INCREF(Py_None);
2030 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002031#undef UTIME_ARG
2032#undef ATIME
2033#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002034}
2035
Guido van Rossum85e3b011991-06-03 12:42:10 +00002036
Guido van Rossum3b066191991-06-04 19:40:25 +00002037/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002038
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002039PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002040"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002042
Barry Warsaw53699e91996-12-10 23:23:01 +00002043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002044posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002045{
2046 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002047 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002048 return NULL;
2049 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002050 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002051}
2052
Martin v. Löwis114619e2002-10-07 06:44:21 +00002053#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2054static void
2055free_string_array(char **array, int count)
2056{
2057 int i;
2058 for (i = 0; i < count; i++)
2059 PyMem_Free(array[i]);
2060 PyMem_DEL(array);
2061}
2062#endif
2063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002064
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002065#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002066PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002067"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068Execute an executable path with arguments, replacing current process.\n\
2069\n\
2070 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002072
Barry Warsaw53699e91996-12-10 23:23:01 +00002073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002074posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002075{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002076 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002077 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002078 char **argvlist;
2079 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002080 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002081
Guido van Rossum89b33251993-10-22 14:26:06 +00002082 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002083 argv is a list or tuple of strings. */
2084
Martin v. Löwis114619e2002-10-07 06:44:21 +00002085 if (!PyArg_ParseTuple(args, "etO:execv",
2086 Py_FileSystemDefaultEncoding,
2087 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002088 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002089 if (PyList_Check(argv)) {
2090 argc = PyList_Size(argv);
2091 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002092 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002093 else if (PyTuple_Check(argv)) {
2094 argc = PyTuple_Size(argv);
2095 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002096 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002097 else {
Fred Drake661ea262000-10-24 19:57:45 +00002098 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002099 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002100 return NULL;
2101 }
2102
2103 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002104 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002105 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002106 return NULL;
2107 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002108
Barry Warsaw53699e91996-12-10 23:23:01 +00002109 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002110 if (argvlist == NULL) {
2111 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002112 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002113 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002114 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002115 if (!PyArg_Parse((*getitem)(argv, i), "et",
2116 Py_FileSystemDefaultEncoding,
2117 &argvlist[i])) {
2118 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002119 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002120 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002121 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002122 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002123
Guido van Rossum85e3b011991-06-03 12:42:10 +00002124 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002125 }
2126 argvlist[argc] = NULL;
2127
Guido van Rossumb6775db1994-08-01 11:34:53 +00002128#ifdef BAD_EXEC_PROTOTYPES
2129 execv(path, (const char **) argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002130#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002131 execv(path, argvlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002132#endif /* BAD_EXEC_PROTOTYPES */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002133
Guido van Rossum85e3b011991-06-03 12:42:10 +00002134 /* If we get here it's definitely an error */
2135
Martin v. Löwis114619e2002-10-07 06:44:21 +00002136 free_string_array(argvlist, argc);
2137 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002138 return posix_error();
2139}
2140
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002141
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002143"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002144Execute a path with arguments and environment, replacing current process.\n\
2145\n\
2146 path: path of executable file\n\
2147 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002148 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002149
Barry Warsaw53699e91996-12-10 23:23:01 +00002150static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002151posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002152{
2153 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002154 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002155 char **argvlist;
2156 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002157 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002158 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002159 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002160 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002161
2162 /* execve has three arguments: (path, argv, env), where
2163 argv is a list or tuple of strings and env is a dictionary
2164 like posix.environ. */
2165
Martin v. Löwis114619e2002-10-07 06:44:21 +00002166 if (!PyArg_ParseTuple(args, "etOO:execve",
2167 Py_FileSystemDefaultEncoding,
2168 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002169 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002170 if (PyList_Check(argv)) {
2171 argc = PyList_Size(argv);
2172 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002173 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002174 else if (PyTuple_Check(argv)) {
2175 argc = PyTuple_Size(argv);
2176 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002177 }
2178 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002179 PyErr_SetString(PyExc_TypeError,
2180 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002181 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002182 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002183 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002184 PyErr_SetString(PyExc_TypeError,
2185 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002186 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002187 }
2188
Guido van Rossum50422b42000-04-26 20:34:28 +00002189 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002190 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002191 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002192 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002193 }
2194
Barry Warsaw53699e91996-12-10 23:23:01 +00002195 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002196 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002197 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002198 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002199 }
2200 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002201 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002202 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002203 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002204 &argvlist[i]))
2205 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002206 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002207 goto fail_1;
2208 }
2209 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002210 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002211 argvlist[argc] = NULL;
2212
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002213 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002214 if (i < 0)
2215 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002216 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002217 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002218 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002219 goto fail_1;
2220 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002221 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002222 keys = PyMapping_Keys(env);
2223 vals = PyMapping_Values(env);
2224 if (!keys || !vals)
2225 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002226 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2227 PyErr_SetString(PyExc_TypeError,
2228 "execve(): env.keys() or env.values() is not a list");
2229 goto fail_2;
2230 }
Tim Peters5aa91602002-01-30 05:46:57 +00002231
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002232 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002233 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002234 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002235
2236 key = PyList_GetItem(keys, pos);
2237 val = PyList_GetItem(vals, pos);
2238 if (!key || !val)
2239 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002240
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002241 if (!PyArg_Parse(
2242 key,
2243 "s;execve() arg 3 contains a non-string key",
2244 &k) ||
2245 !PyArg_Parse(
2246 val,
2247 "s;execve() arg 3 contains a non-string value",
2248 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002249 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002250 goto fail_2;
2251 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002252
2253#if defined(PYOS_OS2)
2254 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2255 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2256#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002257 len = PyString_Size(key) + PyString_Size(val) + 2;
2258 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002259 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002260 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002261 goto fail_2;
2262 }
Tim Petersc8996f52001-12-03 20:41:00 +00002263 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002264 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002265#if defined(PYOS_OS2)
2266 }
2267#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002268 }
2269 envlist[envc] = 0;
2270
Guido van Rossumb6775db1994-08-01 11:34:53 +00002271
2272#ifdef BAD_EXEC_PROTOTYPES
2273 execve(path, (const char **)argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002274#else /* BAD_EXEC_PROTOTYPES */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002275 execve(path, argvlist, envlist);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002276#endif /* BAD_EXEC_PROTOTYPES */
Tim Peters5aa91602002-01-30 05:46:57 +00002277
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002278 /* If we get here it's definitely an error */
2279
2280 (void) posix_error();
2281
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002282 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002283 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002284 PyMem_DEL(envlist[envc]);
2285 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002286 fail_1:
2287 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002288 Py_XDECREF(vals);
2289 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002290 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002291 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002292 return NULL;
2293}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002294#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002296
Guido van Rossuma1065681999-01-25 23:20:23 +00002297#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002298PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002299"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002300Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002301\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002302 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002303 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002304 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002305
2306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002307posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002308{
2309 char *path;
2310 PyObject *argv;
2311 char **argvlist;
2312 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002313 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002314 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002315
2316 /* spawnv has three arguments: (mode, path, argv), where
2317 argv is a list or tuple of strings. */
2318
Martin v. Löwis114619e2002-10-07 06:44:21 +00002319 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2320 Py_FileSystemDefaultEncoding,
2321 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002322 return NULL;
2323 if (PyList_Check(argv)) {
2324 argc = PyList_Size(argv);
2325 getitem = PyList_GetItem;
2326 }
2327 else if (PyTuple_Check(argv)) {
2328 argc = PyTuple_Size(argv);
2329 getitem = PyTuple_GetItem;
2330 }
2331 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002332 PyErr_SetString(PyExc_TypeError,
2333 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002334 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002335 return NULL;
2336 }
2337
2338 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002339 if (argvlist == NULL) {
2340 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002341 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002342 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002343 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002344 if (!PyArg_Parse((*getitem)(argv, i), "et",
2345 Py_FileSystemDefaultEncoding,
2346 &argvlist[i])) {
2347 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002348 PyErr_SetString(
2349 PyExc_TypeError,
2350 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002351 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002352 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002353 }
2354 }
2355 argvlist[argc] = NULL;
2356
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002357#if defined(PYOS_OS2) && defined(PYCC_GCC)
2358 Py_BEGIN_ALLOW_THREADS
2359 spawnval = spawnv(mode, path, argvlist);
2360 Py_END_ALLOW_THREADS
2361#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002362 if (mode == _OLD_P_OVERLAY)
2363 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002364
Tim Peters25059d32001-12-07 20:35:43 +00002365 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002366 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002367 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002368#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002369
Martin v. Löwis114619e2002-10-07 06:44:21 +00002370 free_string_array(argvlist, argc);
2371 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002372
Fred Drake699f3522000-06-29 21:12:41 +00002373 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002374 return posix_error();
2375 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002376#if SIZEOF_LONG == SIZEOF_VOID_P
2377 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002378#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002379 return Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002380#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002381}
2382
2383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002385"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002386Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002387\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002388 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002389 path: path of executable file\n\
2390 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002391 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002392
2393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002394posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002395{
2396 char *path;
2397 PyObject *argv, *env;
2398 char **argvlist;
2399 char **envlist;
2400 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2401 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002402 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002403 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002404 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002405
2406 /* spawnve has four arguments: (mode, path, argv, env), where
2407 argv is a list or tuple of strings and env is a dictionary
2408 like posix.environ. */
2409
Martin v. Löwis114619e2002-10-07 06:44:21 +00002410 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2411 Py_FileSystemDefaultEncoding,
2412 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002413 return NULL;
2414 if (PyList_Check(argv)) {
2415 argc = PyList_Size(argv);
2416 getitem = PyList_GetItem;
2417 }
2418 else if (PyTuple_Check(argv)) {
2419 argc = PyTuple_Size(argv);
2420 getitem = PyTuple_GetItem;
2421 }
2422 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002423 PyErr_SetString(PyExc_TypeError,
2424 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002425 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002426 }
2427 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002428 PyErr_SetString(PyExc_TypeError,
2429 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002430 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002431 }
2432
2433 argvlist = PyMem_NEW(char *, argc+1);
2434 if (argvlist == NULL) {
2435 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002436 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002437 }
2438 for (i = 0; i < argc; i++) {
2439 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002440 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002441 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002442 &argvlist[i]))
2443 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002444 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002445 goto fail_1;
2446 }
2447 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002448 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002449 argvlist[argc] = NULL;
2450
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002451 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002452 if (i < 0)
2453 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002454 envlist = PyMem_NEW(char *, i + 1);
2455 if (envlist == NULL) {
2456 PyErr_NoMemory();
2457 goto fail_1;
2458 }
2459 envc = 0;
2460 keys = PyMapping_Keys(env);
2461 vals = PyMapping_Values(env);
2462 if (!keys || !vals)
2463 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002464 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2465 PyErr_SetString(PyExc_TypeError,
2466 "spawnve(): env.keys() or env.values() is not a list");
2467 goto fail_2;
2468 }
Tim Peters5aa91602002-01-30 05:46:57 +00002469
Guido van Rossuma1065681999-01-25 23:20:23 +00002470 for (pos = 0; pos < i; pos++) {
2471 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002472 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002473
2474 key = PyList_GetItem(keys, pos);
2475 val = PyList_GetItem(vals, pos);
2476 if (!key || !val)
2477 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002478
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002479 if (!PyArg_Parse(
2480 key,
2481 "s;spawnve() arg 3 contains a non-string key",
2482 &k) ||
2483 !PyArg_Parse(
2484 val,
2485 "s;spawnve() arg 3 contains a non-string value",
2486 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002487 {
2488 goto fail_2;
2489 }
Tim Petersc8996f52001-12-03 20:41:00 +00002490 len = PyString_Size(key) + PyString_Size(val) + 2;
2491 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002492 if (p == NULL) {
2493 PyErr_NoMemory();
2494 goto fail_2;
2495 }
Tim Petersc8996f52001-12-03 20:41:00 +00002496 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002497 envlist[envc++] = p;
2498 }
2499 envlist[envc] = 0;
2500
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002501#if defined(PYOS_OS2) && defined(PYCC_GCC)
2502 Py_BEGIN_ALLOW_THREADS
2503 spawnval = spawnve(mode, path, argvlist, envlist);
2504 Py_END_ALLOW_THREADS
2505#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002506 if (mode == _OLD_P_OVERLAY)
2507 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002508
2509 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002510 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002511 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002512#endif
Tim Peters25059d32001-12-07 20:35:43 +00002513
Fred Drake699f3522000-06-29 21:12:41 +00002514 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002515 (void) posix_error();
2516 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002517#if SIZEOF_LONG == SIZEOF_VOID_P
2518 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002519#else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002520 res = Py_BuildValue("L", (LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002521#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002522
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002523 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002524 while (--envc >= 0)
2525 PyMem_DEL(envlist[envc]);
2526 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002527 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002528 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002529 Py_XDECREF(vals);
2530 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002531 fail_0:
2532 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002533 return res;
2534}
2535#endif /* HAVE_SPAWNV */
2536
2537
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002538#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002539PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002540"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002541Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2542\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002543Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002544
2545static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002546posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002547{
Neal Norwitze241ce82003-02-17 18:17:05 +00002548 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002549 if (pid == -1)
2550 return posix_error();
2551 PyOS_AfterFork();
2552 return PyInt_FromLong((long)pid);
2553}
2554#endif
2555
2556
Guido van Rossumad0ee831995-03-01 10:34:45 +00002557#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002558PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002559"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002560Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002561Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002562
Barry Warsaw53699e91996-12-10 23:23:01 +00002563static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002564posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002565{
Neal Norwitze241ce82003-02-17 18:17:05 +00002566 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002567 if (pid == -1)
2568 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002569 if (pid == 0)
2570 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002571 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002572}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002573#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002574
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002575#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002576#ifdef HAVE_PTY_H
2577#include <pty.h>
2578#else
2579#ifdef HAVE_LIBUTIL_H
2580#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002581#endif /* HAVE_LIBUTIL_H */
2582#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002583#ifdef HAVE_STROPTS_H
2584#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002585#endif
2586#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002587
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002588#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002589PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002590"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002591Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002592
2593static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002594posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002595{
2596 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002597#ifndef HAVE_OPENPTY
2598 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002599#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002600#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002601 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002602#ifdef sun
2603 extern char *ptsname();
2604#endif
2605#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002606
Thomas Wouters70c21a12000-07-14 14:28:33 +00002607#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002608 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2609 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002610#elif HAVE__GETPTY
Thomas Wouters70c21a12000-07-14 14:28:33 +00002611 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2612 if (slave_name == NULL)
2613 return posix_error();
2614
2615 slave_fd = open(slave_name, O_RDWR);
2616 if (slave_fd < 0)
2617 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002618#else
2619 master_fd = open("/dev/ptmx", O_RDWR | O_NOCTTY); /* open master */
2620 if (master_fd < 0)
2621 return posix_error();
2622 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002623 /* change permission of slave */
2624 if (grantpt(master_fd) < 0) {
2625 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002626 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002627 }
2628 /* unlock slave */
2629 if (unlockpt(master_fd) < 0) {
2630 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002631 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002632 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002633 signal(SIGCHLD, sig_saved);
2634 slave_name = ptsname(master_fd); /* get name of slave */
2635 if (slave_name == NULL)
2636 return posix_error();
2637 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2638 if (slave_fd < 0)
2639 return posix_error();
2640#ifndef __CYGWIN__
2641 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2642 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002643#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002644 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002645#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002646#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002647#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002648
Fred Drake8cef4cf2000-06-28 16:40:38 +00002649 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002650
Fred Drake8cef4cf2000-06-28 16:40:38 +00002651}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002652#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002653
2654#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002655PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002656"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002657Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2658Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002659To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002660
2661static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002662posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002663{
2664 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002665
Fred Drake8cef4cf2000-06-28 16:40:38 +00002666 pid = forkpty(&master_fd, NULL, NULL, NULL);
2667 if (pid == -1)
2668 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002669 if (pid == 0)
2670 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002671 return Py_BuildValue("(ii)", pid, master_fd);
2672}
2673#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002674
Guido van Rossumad0ee831995-03-01 10:34:45 +00002675#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002676PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002677"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002678Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002679
Barry Warsaw53699e91996-12-10 23:23:01 +00002680static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002681posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002682{
Barry Warsaw53699e91996-12-10 23:23:01 +00002683 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002684}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002685#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002686
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002687
Guido van Rossumad0ee831995-03-01 10:34:45 +00002688#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002689PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002690"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002691Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002692
Barry Warsaw53699e91996-12-10 23:23:01 +00002693static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002694posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002695{
Barry Warsaw53699e91996-12-10 23:23:01 +00002696 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002697}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002698#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002700
Guido van Rossumad0ee831995-03-01 10:34:45 +00002701#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002702PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002703"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002704Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002705
Barry Warsaw53699e91996-12-10 23:23:01 +00002706static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002707posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002708{
Barry Warsaw53699e91996-12-10 23:23:01 +00002709 return PyInt_FromLong((long)getgid());
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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002714PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002715"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002716Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002717
Barry Warsaw53699e91996-12-10 23:23:01 +00002718static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002719posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002720{
Barry Warsaw53699e91996-12-10 23:23:01 +00002721 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002722}
2723
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002724
Fred Drakec9680921999-12-13 16:37:25 +00002725#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002726PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002727"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002728Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00002729
2730static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002731posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00002732{
2733 PyObject *result = NULL;
2734
Fred Drakec9680921999-12-13 16:37:25 +00002735#ifdef NGROUPS_MAX
2736#define MAX_GROUPS NGROUPS_MAX
2737#else
2738 /* defined to be 16 on Solaris7, so this should be a small number */
2739#define MAX_GROUPS 64
2740#endif
2741 gid_t grouplist[MAX_GROUPS];
2742 int n;
2743
2744 n = getgroups(MAX_GROUPS, grouplist);
2745 if (n < 0)
2746 posix_error();
2747 else {
2748 result = PyList_New(n);
2749 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00002750 int i;
2751 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00002752 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00002753 if (o == NULL) {
2754 Py_DECREF(result);
2755 result = NULL;
2756 break;
2757 }
2758 PyList_SET_ITEM(result, i, o);
2759 }
2760 }
2761 }
Neal Norwitze241ce82003-02-17 18:17:05 +00002762
Fred Drakec9680921999-12-13 16:37:25 +00002763 return result;
2764}
2765#endif
2766
Martin v. Löwis606edc12002-06-13 21:09:11 +00002767#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002768PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002769"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00002770Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00002771
2772static PyObject *
2773posix_getpgid(PyObject *self, PyObject *args)
2774{
2775 int pid, pgid;
2776 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
2777 return NULL;
2778 pgid = getpgid(pid);
2779 if (pgid < 0)
2780 return posix_error();
2781 return PyInt_FromLong((long)pgid);
2782}
2783#endif /* HAVE_GETPGID */
2784
2785
Guido van Rossumb6775db1994-08-01 11:34:53 +00002786#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002787PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002788"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002789Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002790
Barry Warsaw53699e91996-12-10 23:23:01 +00002791static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002792posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00002793{
Guido van Rossumb6775db1994-08-01 11:34:53 +00002794#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00002795 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002796#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00002797 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002798#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00002799}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002800#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00002801
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002802
Guido van Rossumb6775db1994-08-01 11:34:53 +00002803#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002804PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002805"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002806Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002807
Barry Warsaw53699e91996-12-10 23:23:01 +00002808static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002809posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00002810{
Guido van Rossum64933891994-10-20 21:56:42 +00002811#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00002812 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002813#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00002814 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00002815#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00002816 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002817 Py_INCREF(Py_None);
2818 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00002819}
2820
Guido van Rossumb6775db1994-08-01 11:34:53 +00002821#endif /* HAVE_SETPGRP */
2822
Guido van Rossumad0ee831995-03-01 10:34:45 +00002823#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002824PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002825"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002826Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002827
Barry Warsaw53699e91996-12-10 23:23:01 +00002828static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002829posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002830{
Barry Warsaw53699e91996-12-10 23:23:01 +00002831 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00002832}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002833#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002834
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002835
Fred Drake12c6e2d1999-12-14 21:25:03 +00002836#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002837PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002838"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002839Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00002840
2841static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002842posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00002843{
Neal Norwitze241ce82003-02-17 18:17:05 +00002844 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00002845 char *name;
2846 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00002847
Fred Drakea30680b2000-12-06 21:24:28 +00002848 errno = 0;
2849 name = getlogin();
2850 if (name == NULL) {
2851 if (errno)
2852 posix_error();
2853 else
2854 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00002855 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00002856 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00002857 else
2858 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00002859 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00002860
Fred Drake12c6e2d1999-12-14 21:25:03 +00002861 return result;
2862}
2863#endif
2864
Guido van Rossumad0ee831995-03-01 10:34:45 +00002865#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002866PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002867"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002868Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002869
Barry Warsaw53699e91996-12-10 23:23:01 +00002870static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002871posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002872{
Barry Warsaw53699e91996-12-10 23:23:01 +00002873 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002874}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002875#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002876
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002877
Guido van Rossumad0ee831995-03-01 10:34:45 +00002878#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002879PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002880"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002881Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002882
Barry Warsaw53699e91996-12-10 23:23:01 +00002883static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002884posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002885{
2886 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002887 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002888 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002889#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002890 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
2891 APIRET rc;
2892 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002893 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002894
2895 } else if (sig == XCPT_SIGNAL_KILLPROC) {
2896 APIRET rc;
2897 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002898 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002899
2900 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002901 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002902#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00002903 if (kill(pid, sig) == -1)
2904 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002905#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002906 Py_INCREF(Py_None);
2907 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002908}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002909#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002910
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002911#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002912PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002913"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002914Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00002915
2916static PyObject *
2917posix_killpg(PyObject *self, PyObject *args)
2918{
2919 int pgid, sig;
2920 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
2921 return NULL;
2922 if (killpg(pgid, sig) == -1)
2923 return posix_error();
2924 Py_INCREF(Py_None);
2925 return Py_None;
2926}
2927#endif
2928
Guido van Rossumc0125471996-06-28 18:55:32 +00002929#ifdef HAVE_PLOCK
2930
2931#ifdef HAVE_SYS_LOCK_H
2932#include <sys/lock.h>
2933#endif
2934
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002935PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002936"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002937Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002938
Barry Warsaw53699e91996-12-10 23:23:01 +00002939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002940posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00002941{
2942 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002943 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00002944 return NULL;
2945 if (plock(op) == -1)
2946 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002947 Py_INCREF(Py_None);
2948 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00002949}
2950#endif
2951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002952
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002953#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002954PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002955"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002956Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002957
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002958#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002959#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00002960static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002961async_system(const char *command)
2962{
2963 char *p, errormsg[256], args[1024];
2964 RESULTCODES rcodes;
2965 APIRET rc;
2966 char *shell = getenv("COMSPEC");
2967 if (!shell)
2968 shell = "cmd";
2969
2970 strcpy(args, shell);
2971 p = &args[ strlen(args)+1 ];
2972 strcpy(p, "/c ");
2973 strcat(p, command);
2974 p += strlen(p) + 1;
2975 *p = '\0';
2976
2977 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002978 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002979 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002980 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002981 &rcodes, shell);
2982 return rc;
2983}
2984
Guido van Rossumd48f2521997-12-05 22:19:34 +00002985static FILE *
2986popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002987{
2988 HFILE rhan, whan;
2989 FILE *retfd = NULL;
2990 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
2991
Guido van Rossumd48f2521997-12-05 22:19:34 +00002992 if (rc != NO_ERROR) {
2993 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002994 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00002995 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002996
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002997 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2998 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002999
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003000 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3001 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003002
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003003 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3004 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003005
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003006 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003007 }
3008
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003009 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3010 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003011
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003012 if (rc == NO_ERROR)
3013 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3014
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003015 close(oldfd); /* And Close Saved STDOUT Handle */
3016 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003017
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003018 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3019 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003020
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003021 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3022 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003023
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003024 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3025 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003026
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003027 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003028 }
3029
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003030 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3031 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003032
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003033 if (rc == NO_ERROR)
3034 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3035
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003036 close(oldfd); /* And Close Saved STDIN Handle */
3037 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003038
Guido van Rossumd48f2521997-12-05 22:19:34 +00003039 } else {
3040 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003041 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003042 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003043}
3044
3045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003046posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003047{
3048 char *name;
3049 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003050 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003051 FILE *fp;
3052 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003053 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003054 return NULL;
3055 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003056 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003057 Py_END_ALLOW_THREADS
3058 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003059 return os2_error(err);
3060
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003061 f = PyFile_FromFile(fp, name, mode, fclose);
3062 if (f != NULL)
3063 PyFile_SetBufSize(f, bufsize);
3064 return f;
3065}
3066
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003067#elif defined(PYCC_GCC)
3068
3069/* standard posix version of popen() support */
3070static PyObject *
3071posix_popen(PyObject *self, PyObject *args)
3072{
3073 char *name;
3074 char *mode = "r";
3075 int bufsize = -1;
3076 FILE *fp;
3077 PyObject *f;
3078 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3079 return NULL;
3080 Py_BEGIN_ALLOW_THREADS
3081 fp = popen(name, mode);
3082 Py_END_ALLOW_THREADS
3083 if (fp == NULL)
3084 return posix_error();
3085 f = PyFile_FromFile(fp, name, mode, pclose);
3086 if (f != NULL)
3087 PyFile_SetBufSize(f, bufsize);
3088 return f;
3089}
3090
3091/* fork() under OS/2 has lots'o'warts
3092 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3093 * most of this code is a ripoff of the win32 code, but using the
3094 * capabilities of EMX's C library routines
3095 */
3096
3097/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3098#define POPEN_1 1
3099#define POPEN_2 2
3100#define POPEN_3 3
3101#define POPEN_4 4
3102
3103static PyObject *_PyPopen(char *, int, int, int);
3104static int _PyPclose(FILE *file);
3105
3106/*
3107 * Internal dictionary mapping popen* file pointers to process handles,
3108 * for use when retrieving the process exit code. See _PyPclose() below
3109 * for more information on this dictionary's use.
3110 */
3111static PyObject *_PyPopenProcs = NULL;
3112
3113/* os2emx version of popen2()
3114 *
3115 * The result of this function is a pipe (file) connected to the
3116 * process's stdin, and a pipe connected to the process's stdout.
3117 */
3118
3119static PyObject *
3120os2emx_popen2(PyObject *self, PyObject *args)
3121{
3122 PyObject *f;
3123 int tm=0;
3124
3125 char *cmdstring;
3126 char *mode = "t";
3127 int bufsize = -1;
3128 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3129 return NULL;
3130
3131 if (*mode == 't')
3132 tm = O_TEXT;
3133 else if (*mode != 'b') {
3134 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3135 return NULL;
3136 } else
3137 tm = O_BINARY;
3138
3139 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3140
3141 return f;
3142}
3143
3144/*
3145 * Variation on os2emx.popen2
3146 *
3147 * The result of this function is 3 pipes - the process's stdin,
3148 * stdout and stderr
3149 */
3150
3151static PyObject *
3152os2emx_popen3(PyObject *self, PyObject *args)
3153{
3154 PyObject *f;
3155 int tm = 0;
3156
3157 char *cmdstring;
3158 char *mode = "t";
3159 int bufsize = -1;
3160 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3161 return NULL;
3162
3163 if (*mode == 't')
3164 tm = O_TEXT;
3165 else if (*mode != 'b') {
3166 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3167 return NULL;
3168 } else
3169 tm = O_BINARY;
3170
3171 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3172
3173 return f;
3174}
3175
3176/*
3177 * Variation on os2emx.popen2
3178 *
3179 * The result of this function is 2 pipes - the processes stdin,
3180 * and stdout+stderr combined as a single pipe.
3181 */
3182
3183static PyObject *
3184os2emx_popen4(PyObject *self, PyObject *args)
3185{
3186 PyObject *f;
3187 int tm = 0;
3188
3189 char *cmdstring;
3190 char *mode = "t";
3191 int bufsize = -1;
3192 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3193 return NULL;
3194
3195 if (*mode == 't')
3196 tm = O_TEXT;
3197 else if (*mode != 'b') {
3198 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3199 return NULL;
3200 } else
3201 tm = O_BINARY;
3202
3203 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3204
3205 return f;
3206}
3207
3208/* a couple of structures for convenient handling of multiple
3209 * file handles and pipes
3210 */
3211struct file_ref
3212{
3213 int handle;
3214 int flags;
3215};
3216
3217struct pipe_ref
3218{
3219 int rd;
3220 int wr;
3221};
3222
3223/* The following code is derived from the win32 code */
3224
3225static PyObject *
3226_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3227{
3228 struct file_ref stdio[3];
3229 struct pipe_ref p_fd[3];
3230 FILE *p_s[3];
3231 int file_count, i, pipe_err, pipe_pid;
3232 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3233 PyObject *f, *p_f[3];
3234
3235 /* file modes for subsequent fdopen's on pipe handles */
3236 if (mode == O_TEXT)
3237 {
3238 rd_mode = "rt";
3239 wr_mode = "wt";
3240 }
3241 else
3242 {
3243 rd_mode = "rb";
3244 wr_mode = "wb";
3245 }
3246
3247 /* prepare shell references */
3248 if ((shell = getenv("EMXSHELL")) == NULL)
3249 if ((shell = getenv("COMSPEC")) == NULL)
3250 {
3251 errno = ENOENT;
3252 return posix_error();
3253 }
3254
3255 sh_name = _getname(shell);
3256 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3257 opt = "/c";
3258 else
3259 opt = "-c";
3260
3261 /* save current stdio fds + their flags, and set not inheritable */
3262 i = pipe_err = 0;
3263 while (pipe_err >= 0 && i < 3)
3264 {
3265 pipe_err = stdio[i].handle = dup(i);
3266 stdio[i].flags = fcntl(i, F_GETFD, 0);
3267 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3268 i++;
3269 }
3270 if (pipe_err < 0)
3271 {
3272 /* didn't get them all saved - clean up and bail out */
3273 int saved_err = errno;
3274 while (i-- > 0)
3275 {
3276 close(stdio[i].handle);
3277 }
3278 errno = saved_err;
3279 return posix_error();
3280 }
3281
3282 /* create pipe ends */
3283 file_count = 2;
3284 if (n == POPEN_3)
3285 file_count = 3;
3286 i = pipe_err = 0;
3287 while ((pipe_err == 0) && (i < file_count))
3288 pipe_err = pipe((int *)&p_fd[i++]);
3289 if (pipe_err < 0)
3290 {
3291 /* didn't get them all made - clean up and bail out */
3292 while (i-- > 0)
3293 {
3294 close(p_fd[i].wr);
3295 close(p_fd[i].rd);
3296 }
3297 errno = EPIPE;
3298 return posix_error();
3299 }
3300
3301 /* change the actual standard IO streams over temporarily,
3302 * making the retained pipe ends non-inheritable
3303 */
3304 pipe_err = 0;
3305
3306 /* - stdin */
3307 if (dup2(p_fd[0].rd, 0) == 0)
3308 {
3309 close(p_fd[0].rd);
3310 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3311 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3312 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3313 {
3314 close(p_fd[0].wr);
3315 pipe_err = -1;
3316 }
3317 }
3318 else
3319 {
3320 pipe_err = -1;
3321 }
3322
3323 /* - stdout */
3324 if (pipe_err == 0)
3325 {
3326 if (dup2(p_fd[1].wr, 1) == 1)
3327 {
3328 close(p_fd[1].wr);
3329 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3330 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3331 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3332 {
3333 close(p_fd[1].rd);
3334 pipe_err = -1;
3335 }
3336 }
3337 else
3338 {
3339 pipe_err = -1;
3340 }
3341 }
3342
3343 /* - stderr, as required */
3344 if (pipe_err == 0)
3345 switch (n)
3346 {
3347 case POPEN_3:
3348 {
3349 if (dup2(p_fd[2].wr, 2) == 2)
3350 {
3351 close(p_fd[2].wr);
3352 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3353 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3354 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3355 {
3356 close(p_fd[2].rd);
3357 pipe_err = -1;
3358 }
3359 }
3360 else
3361 {
3362 pipe_err = -1;
3363 }
3364 break;
3365 }
3366
3367 case POPEN_4:
3368 {
3369 if (dup2(1, 2) != 2)
3370 {
3371 pipe_err = -1;
3372 }
3373 break;
3374 }
3375 }
3376
3377 /* spawn the child process */
3378 if (pipe_err == 0)
3379 {
3380 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3381 if (pipe_pid == -1)
3382 {
3383 pipe_err = -1;
3384 }
3385 else
3386 {
3387 /* save the PID into the FILE structure
3388 * NOTE: this implementation doesn't actually
3389 * take advantage of this, but do it for
3390 * completeness - AIM Apr01
3391 */
3392 for (i = 0; i < file_count; i++)
3393 p_s[i]->_pid = pipe_pid;
3394 }
3395 }
3396
3397 /* reset standard IO to normal */
3398 for (i = 0; i < 3; i++)
3399 {
3400 dup2(stdio[i].handle, i);
3401 fcntl(i, F_SETFD, stdio[i].flags);
3402 close(stdio[i].handle);
3403 }
3404
3405 /* if any remnant problems, clean up and bail out */
3406 if (pipe_err < 0)
3407 {
3408 for (i = 0; i < 3; i++)
3409 {
3410 close(p_fd[i].rd);
3411 close(p_fd[i].wr);
3412 }
3413 errno = EPIPE;
3414 return posix_error_with_filename(cmdstring);
3415 }
3416
3417 /* build tuple of file objects to return */
3418 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3419 PyFile_SetBufSize(p_f[0], bufsize);
3420 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3421 PyFile_SetBufSize(p_f[1], bufsize);
3422 if (n == POPEN_3)
3423 {
3424 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3425 PyFile_SetBufSize(p_f[0], bufsize);
3426 f = Py_BuildValue("OOO", p_f[0], p_f[1], p_f[2]);
3427 }
3428 else
3429 f = Py_BuildValue("OO", p_f[0], p_f[1]);
3430
3431 /*
3432 * Insert the files we've created into the process dictionary
3433 * all referencing the list with the process handle and the
3434 * initial number of files (see description below in _PyPclose).
3435 * Since if _PyPclose later tried to wait on a process when all
3436 * handles weren't closed, it could create a deadlock with the
3437 * child, we spend some energy here to try to ensure that we
3438 * either insert all file handles into the dictionary or none
3439 * at all. It's a little clumsy with the various popen modes
3440 * and variable number of files involved.
3441 */
3442 if (!_PyPopenProcs)
3443 {
3444 _PyPopenProcs = PyDict_New();
3445 }
3446
3447 if (_PyPopenProcs)
3448 {
3449 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3450 int ins_rc[3];
3451
3452 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3453 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3454
3455 procObj = PyList_New(2);
3456 pidObj = PyInt_FromLong((long) pipe_pid);
3457 intObj = PyInt_FromLong((long) file_count);
3458
3459 if (procObj && pidObj && intObj)
3460 {
3461 PyList_SetItem(procObj, 0, pidObj);
3462 PyList_SetItem(procObj, 1, intObj);
3463
3464 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3465 if (fileObj[0])
3466 {
3467 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3468 fileObj[0],
3469 procObj);
3470 }
3471 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3472 if (fileObj[1])
3473 {
3474 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3475 fileObj[1],
3476 procObj);
3477 }
3478 if (file_count >= 3)
3479 {
3480 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3481 if (fileObj[2])
3482 {
3483 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3484 fileObj[2],
3485 procObj);
3486 }
3487 }
3488
3489 if (ins_rc[0] < 0 || !fileObj[0] ||
3490 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3491 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3492 {
3493 /* Something failed - remove any dictionary
3494 * entries that did make it.
3495 */
3496 if (!ins_rc[0] && fileObj[0])
3497 {
3498 PyDict_DelItem(_PyPopenProcs,
3499 fileObj[0]);
3500 }
3501 if (!ins_rc[1] && fileObj[1])
3502 {
3503 PyDict_DelItem(_PyPopenProcs,
3504 fileObj[1]);
3505 }
3506 if (!ins_rc[2] && fileObj[2])
3507 {
3508 PyDict_DelItem(_PyPopenProcs,
3509 fileObj[2]);
3510 }
3511 }
3512 }
3513
3514 /*
3515 * Clean up our localized references for the dictionary keys
3516 * and value since PyDict_SetItem will Py_INCREF any copies
3517 * that got placed in the dictionary.
3518 */
3519 Py_XDECREF(procObj);
3520 Py_XDECREF(fileObj[0]);
3521 Py_XDECREF(fileObj[1]);
3522 Py_XDECREF(fileObj[2]);
3523 }
3524
3525 /* Child is launched. */
3526 return f;
3527}
3528
3529/*
3530 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3531 * exit code for the child process and return as a result of the close.
3532 *
3533 * This function uses the _PyPopenProcs dictionary in order to map the
3534 * input file pointer to information about the process that was
3535 * originally created by the popen* call that created the file pointer.
3536 * The dictionary uses the file pointer as a key (with one entry
3537 * inserted for each file returned by the original popen* call) and a
3538 * single list object as the value for all files from a single call.
3539 * The list object contains the Win32 process handle at [0], and a file
3540 * count at [1], which is initialized to the total number of file
3541 * handles using that list.
3542 *
3543 * This function closes whichever handle it is passed, and decrements
3544 * the file count in the dictionary for the process handle pointed to
3545 * by this file. On the last close (when the file count reaches zero),
3546 * this function will wait for the child process and then return its
3547 * exit code as the result of the close() operation. This permits the
3548 * files to be closed in any order - it is always the close() of the
3549 * final handle that will return the exit code.
3550 */
3551
3552 /* RED_FLAG 31-Aug-2000 Tim
3553 * This is always called (today!) between a pair of
3554 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
3555 * macros. So the thread running this has no valid thread state, as
3556 * far as Python is concerned. However, this calls some Python API
3557 * functions that cannot be called safely without a valid thread
3558 * state, in particular PyDict_GetItem.
3559 * As a temporary hack (although it may last for years ...), we
3560 * *rely* on not having a valid thread state in this function, in
3561 * order to create our own "from scratch".
3562 * This will deadlock if _PyPclose is ever called by a thread
3563 * holding the global lock.
3564 * (The OS/2 EMX thread support appears to cover the case where the
3565 * lock is already held - AIM Apr01)
3566 */
3567
3568static int _PyPclose(FILE *file)
3569{
3570 int result;
3571 int exit_code;
3572 int pipe_pid;
3573 PyObject *procObj, *pidObj, *intObj, *fileObj;
3574 int file_count;
3575#ifdef WITH_THREAD
3576 PyInterpreterState* pInterpreterState;
3577 PyThreadState* pThreadState;
3578#endif
3579
3580 /* Close the file handle first, to ensure it can't block the
3581 * child from exiting if it's the last handle.
3582 */
3583 result = fclose(file);
3584
3585#ifdef WITH_THREAD
3586 /* Bootstrap a valid thread state into existence. */
3587 pInterpreterState = PyInterpreterState_New();
3588 if (!pInterpreterState) {
3589 /* Well, we're hosed now! We don't have a thread
3590 * state, so can't call a nice error routine, or raise
3591 * an exception. Just die.
3592 */
3593 Py_FatalError("unable to allocate interpreter state "
3594 "when closing popen object.");
3595 return -1; /* unreachable */
3596 }
3597 pThreadState = PyThreadState_New(pInterpreterState);
3598 if (!pThreadState) {
3599 Py_FatalError("unable to allocate thread state "
3600 "when closing popen object.");
3601 return -1; /* unreachable */
3602 }
3603 /* Grab the global lock. Note that this will deadlock if the
3604 * current thread already has the lock! (see RED_FLAG comments
3605 * before this function)
3606 */
3607 PyEval_RestoreThread(pThreadState);
3608#endif
3609
3610 if (_PyPopenProcs)
3611 {
3612 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3613 (procObj = PyDict_GetItem(_PyPopenProcs,
3614 fileObj)) != NULL &&
3615 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3616 (intObj = PyList_GetItem(procObj,1)) != NULL)
3617 {
3618 pipe_pid = (int) PyInt_AsLong(pidObj);
3619 file_count = (int) PyInt_AsLong(intObj);
3620
3621 if (file_count > 1)
3622 {
3623 /* Still other files referencing process */
3624 file_count--;
3625 PyList_SetItem(procObj,1,
3626 PyInt_FromLong((long) file_count));
3627 }
3628 else
3629 {
3630 /* Last file for this process */
3631 if (result != EOF &&
3632 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3633 {
3634 /* extract exit status */
3635 if (WIFEXITED(exit_code))
3636 {
3637 result = WEXITSTATUS(exit_code);
3638 }
3639 else
3640 {
3641 errno = EPIPE;
3642 result = -1;
3643 }
3644 }
3645 else
3646 {
3647 /* Indicate failure - this will cause the file object
3648 * to raise an I/O error and translate the last
3649 * error code from errno. We do have a problem with
3650 * last errors that overlap the normal errno table,
3651 * but that's a consistent problem with the file object.
3652 */
3653 result = -1;
3654 }
3655 }
3656
3657 /* Remove this file pointer from dictionary */
3658 PyDict_DelItem(_PyPopenProcs, fileObj);
3659
3660 if (PyDict_Size(_PyPopenProcs) == 0)
3661 {
3662 Py_DECREF(_PyPopenProcs);
3663 _PyPopenProcs = NULL;
3664 }
3665
3666 } /* if object retrieval ok */
3667
3668 Py_XDECREF(fileObj);
3669 } /* if _PyPopenProcs */
3670
3671#ifdef WITH_THREAD
3672 /* Tear down the thread & interpreter states.
3673 * Note that interpreter state clear & delete functions automatically
3674 * call the thread clear & delete functions, and indeed insist on
3675 * doing that themselves. The lock must be held during the clear, but
3676 * need not be held during the delete.
3677 */
3678 PyInterpreterState_Clear(pInterpreterState);
3679 PyEval_ReleaseThread(pThreadState);
3680 PyInterpreterState_Delete(pInterpreterState);
3681#endif
3682
3683 return result;
3684}
3685
3686#endif /* PYCC_??? */
3687
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003688#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003689
3690/*
3691 * Portable 'popen' replacement for Win32.
3692 *
3693 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3694 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003695 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003696 */
3697
3698#include <malloc.h>
3699#include <io.h>
3700#include <fcntl.h>
3701
3702/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3703#define POPEN_1 1
3704#define POPEN_2 2
3705#define POPEN_3 3
3706#define POPEN_4 4
3707
3708static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003709static int _PyPclose(FILE *file);
3710
3711/*
3712 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003713 * for use when retrieving the process exit code. See _PyPclose() below
3714 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003715 */
3716static PyObject *_PyPopenProcs = NULL;
3717
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003718
3719/* popen that works from a GUI.
3720 *
3721 * The result of this function is a pipe (file) connected to the
3722 * processes stdin or stdout, depending on the requested mode.
3723 */
3724
3725static PyObject *
3726posix_popen(PyObject *self, PyObject *args)
3727{
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003728 PyObject *f, *s;
3729 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003730
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003731 char *cmdstring;
3732 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003733 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003734 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003735 return NULL;
3736
3737 s = PyTuple_New(0);
Tim Peters5aa91602002-01-30 05:46:57 +00003738
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003739 if (*mode == 'r')
3740 tm = _O_RDONLY;
3741 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003742 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003743 return NULL;
3744 } else
3745 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003746
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003747 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003748 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003749 return NULL;
3750 }
3751
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003752 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003753 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003754 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003755 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003756 else
3757 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3758
3759 return f;
3760}
3761
3762/* Variation on win32pipe.popen
3763 *
3764 * The result of this function is a pipe (file) connected to the
3765 * process's stdin, and a pipe connected to the process's stdout.
3766 */
3767
3768static PyObject *
3769win32_popen2(PyObject *self, PyObject *args)
3770{
3771 PyObject *f;
3772 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00003773
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003774 char *cmdstring;
3775 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003776 int bufsize = -1;
3777 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003778 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003779
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003780 if (*mode == 't')
3781 tm = _O_TEXT;
3782 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003783 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003784 return NULL;
3785 } else
3786 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003787
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003788 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003789 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003790 return NULL;
3791 }
3792
3793 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00003794
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003795 return f;
3796}
3797
3798/*
3799 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003800 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003801 * The result of this function is 3 pipes - the process's stdin,
3802 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003803 */
3804
3805static PyObject *
3806win32_popen3(PyObject *self, PyObject *args)
3807{
3808 PyObject *f;
3809 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003810
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003811 char *cmdstring;
3812 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003813 int bufsize = -1;
3814 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003815 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003816
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003817 if (*mode == 't')
3818 tm = _O_TEXT;
3819 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003820 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003821 return NULL;
3822 } else
3823 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00003824
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003825 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003826 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003827 return NULL;
3828 }
3829
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003830 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00003831
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003832 return f;
3833}
3834
3835/*
3836 * Variation on win32pipe.popen
3837 *
Tim Peters5aa91602002-01-30 05:46:57 +00003838 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003839 * and stdout+stderr combined as a single pipe.
3840 */
3841
3842static PyObject *
3843win32_popen4(PyObject *self, PyObject *args)
3844{
3845 PyObject *f;
3846 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003847
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003848 char *cmdstring;
3849 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003850 int bufsize = -1;
3851 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003852 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00003853
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003854 if (*mode == 't')
3855 tm = _O_TEXT;
3856 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00003857 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003858 return NULL;
3859 } else
3860 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003861
3862 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003863 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003864 return NULL;
3865 }
3866
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003867 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003868
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003869 return f;
3870}
3871
Mark Hammond08501372001-01-31 07:30:29 +00003872static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00003873_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00003874 HANDLE hStdin,
3875 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00003876 HANDLE hStderr,
3877 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003878{
3879 PROCESS_INFORMATION piProcInfo;
3880 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003881 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003882 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00003883 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003884 int i;
3885 int x;
3886
3887 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00003888 char *comshell;
3889
Tim Peters92e4dd82002-10-05 01:47:34 +00003890 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003891 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
3892 return x;
Tim Peters402d5982001-08-27 06:37:48 +00003893
3894 /* Explicitly check if we are using COMMAND.COM. If we are
3895 * then use the w9xpopen hack.
3896 */
3897 comshell = s1 + x;
3898 while (comshell >= s1 && *comshell != '\\')
3899 --comshell;
3900 ++comshell;
3901
3902 if (GetVersion() < 0x80000000 &&
3903 _stricmp(comshell, "command.com") != 0) {
3904 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003905 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00003906 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003907 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00003908 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003909 }
3910 else {
3911 /*
Tim Peters402d5982001-08-27 06:37:48 +00003912 * Oh gag, we're on Win9x or using COMMAND.COM. Use
3913 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003914 */
Mark Hammond08501372001-01-31 07:30:29 +00003915 char modulepath[_MAX_PATH];
3916 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003917 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
3918 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003919 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003920 x = i+1;
3921 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00003922 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00003923 strncat(modulepath,
3924 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003925 (sizeof(modulepath)/sizeof(modulepath[0]))
3926 -strlen(modulepath));
3927 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003928 /* Eeek - file-not-found - possibly an embedding
3929 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00003930 */
Tim Peters5aa91602002-01-30 05:46:57 +00003931 strncpy(modulepath,
3932 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00003933 sizeof(modulepath)/sizeof(modulepath[0]));
3934 if (modulepath[strlen(modulepath)-1] != '\\')
3935 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00003936 strncat(modulepath,
3937 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00003938 (sizeof(modulepath)/sizeof(modulepath[0]))
3939 -strlen(modulepath));
3940 /* No where else to look - raise an easily identifiable
3941 error, rather than leaving Windows to report
3942 "file not found" - as the user is probably blissfully
3943 unaware this shim EXE is used, and it will confuse them.
3944 (well, it confused me for a while ;-)
3945 */
3946 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00003947 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00003948 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00003949 "for popen to work with your shell "
3950 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00003951 szConsoleSpawn);
3952 return FALSE;
3953 }
3954 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003955 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00003956 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003957 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00003958
Tim Peters92e4dd82002-10-05 01:47:34 +00003959 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003960 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003961 /* To maintain correct argument passing semantics,
3962 we pass the command-line as it stands, and allow
3963 quoting to be applied. w9xpopen.exe will then
3964 use its argv vector, and re-quote the necessary
3965 args for the ultimate child process.
3966 */
Tim Peters75cdad52001-11-28 22:07:30 +00003967 PyOS_snprintf(
3968 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00003969 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003970 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003971 s1,
3972 s3,
3973 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00003974 /* Not passing CREATE_NEW_CONSOLE has been known to
3975 cause random failures on win9x. Specifically a
3976 dialog:
3977 "Your program accessed mem currently in use at xxx"
3978 and a hopeful warning about the stability of your
3979 system.
3980 Cost is Ctrl+C wont kill children, but anyone
3981 who cares can have a go!
3982 */
3983 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003984 }
3985 }
3986
3987 /* Could be an else here to try cmd.exe / command.com in the path
3988 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00003989 else {
Tim Peters402d5982001-08-27 06:37:48 +00003990 PyErr_SetString(PyExc_RuntimeError,
3991 "Cannot locate a COMSPEC environment variable to "
3992 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00003993 return FALSE;
3994 }
Tim Peters5aa91602002-01-30 05:46:57 +00003995
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003996 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
3997 siStartInfo.cb = sizeof(STARTUPINFO);
3998 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
3999 siStartInfo.hStdInput = hStdin;
4000 siStartInfo.hStdOutput = hStdout;
4001 siStartInfo.hStdError = hStderr;
4002 siStartInfo.wShowWindow = SW_HIDE;
4003
4004 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004005 s2,
4006 NULL,
4007 NULL,
4008 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004009 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004010 NULL,
4011 NULL,
4012 &siStartInfo,
4013 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004014 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004015 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004016
Mark Hammondb37a3732000-08-14 04:47:33 +00004017 /* Return process handle */
4018 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004019 return TRUE;
4020 }
Tim Peters402d5982001-08-27 06:37:48 +00004021 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004022 return FALSE;
4023}
4024
4025/* The following code is based off of KB: Q190351 */
4026
4027static PyObject *
4028_PyPopen(char *cmdstring, int mode, int n)
4029{
4030 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4031 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004032 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004033
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004034 SECURITY_ATTRIBUTES saAttr;
4035 BOOL fSuccess;
4036 int fd1, fd2, fd3;
4037 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004038 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004039 PyObject *f;
4040
4041 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4042 saAttr.bInheritHandle = TRUE;
4043 saAttr.lpSecurityDescriptor = NULL;
4044
4045 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4046 return win32_error("CreatePipe", NULL);
4047
4048 /* Create new output read handle and the input write handle. Set
4049 * the inheritance properties to FALSE. Otherwise, the child inherits
4050 * the these handles; resulting in non-closeable handles to the pipes
4051 * being created. */
4052 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004053 GetCurrentProcess(), &hChildStdinWrDup, 0,
4054 FALSE,
4055 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004056 if (!fSuccess)
4057 return win32_error("DuplicateHandle", NULL);
4058
4059 /* Close the inheritable version of ChildStdin
4060 that we're using. */
4061 CloseHandle(hChildStdinWr);
4062
4063 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4064 return win32_error("CreatePipe", NULL);
4065
4066 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004067 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4068 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004069 if (!fSuccess)
4070 return win32_error("DuplicateHandle", NULL);
4071
4072 /* Close the inheritable version of ChildStdout
4073 that we're using. */
4074 CloseHandle(hChildStdoutRd);
4075
4076 if (n != POPEN_4) {
4077 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4078 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004079 fSuccess = DuplicateHandle(GetCurrentProcess(),
4080 hChildStderrRd,
4081 GetCurrentProcess(),
4082 &hChildStderrRdDup, 0,
4083 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004084 if (!fSuccess)
4085 return win32_error("DuplicateHandle", NULL);
4086 /* Close the inheritable version of ChildStdErr that we're using. */
4087 CloseHandle(hChildStderrRd);
4088 }
Tim Peters5aa91602002-01-30 05:46:57 +00004089
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004090 switch (n) {
4091 case POPEN_1:
4092 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4093 case _O_WRONLY | _O_TEXT:
4094 /* Case for writing to child Stdin in text mode. */
4095 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4096 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004097 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004098 PyFile_SetBufSize(f, 0);
4099 /* We don't care about these pipes anymore, so close them. */
4100 CloseHandle(hChildStdoutRdDup);
4101 CloseHandle(hChildStderrRdDup);
4102 break;
4103
4104 case _O_RDONLY | _O_TEXT:
4105 /* Case for reading from child Stdout in text mode. */
4106 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4107 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004108 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004109 PyFile_SetBufSize(f, 0);
4110 /* We don't care about these pipes anymore, so close them. */
4111 CloseHandle(hChildStdinWrDup);
4112 CloseHandle(hChildStderrRdDup);
4113 break;
4114
4115 case _O_RDONLY | _O_BINARY:
4116 /* Case for readinig from child Stdout in binary mode. */
4117 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4118 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004119 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004120 PyFile_SetBufSize(f, 0);
4121 /* We don't care about these pipes anymore, so close them. */
4122 CloseHandle(hChildStdinWrDup);
4123 CloseHandle(hChildStderrRdDup);
4124 break;
4125
4126 case _O_WRONLY | _O_BINARY:
4127 /* Case for writing to child Stdin in binary mode. */
4128 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4129 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004130 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004131 PyFile_SetBufSize(f, 0);
4132 /* We don't care about these pipes anymore, so close them. */
4133 CloseHandle(hChildStdoutRdDup);
4134 CloseHandle(hChildStderrRdDup);
4135 break;
4136 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004137 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004138 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004139
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004140 case POPEN_2:
4141 case POPEN_4:
4142 {
4143 char *m1, *m2;
4144 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004145
Tim Peters7dca21e2002-08-19 00:42:29 +00004146 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004147 m1 = "r";
4148 m2 = "w";
4149 } else {
4150 m1 = "rb";
4151 m2 = "wb";
4152 }
4153
4154 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4155 f1 = _fdopen(fd1, m2);
4156 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4157 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004158 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004159 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004160 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004161 PyFile_SetBufSize(p2, 0);
4162
4163 if (n != 4)
4164 CloseHandle(hChildStderrRdDup);
4165
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004166 f = Py_BuildValue("OO",p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004167 Py_XDECREF(p1);
4168 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004169 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004170 break;
4171 }
Tim Peters5aa91602002-01-30 05:46:57 +00004172
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004173 case POPEN_3:
4174 {
4175 char *m1, *m2;
4176 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004177
Tim Peters7dca21e2002-08-19 00:42:29 +00004178 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004179 m1 = "r";
4180 m2 = "w";
4181 } else {
4182 m1 = "rb";
4183 m2 = "wb";
4184 }
4185
4186 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4187 f1 = _fdopen(fd1, m2);
4188 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4189 f2 = _fdopen(fd2, m1);
4190 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4191 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004192 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004193 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4194 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004195 PyFile_SetBufSize(p1, 0);
4196 PyFile_SetBufSize(p2, 0);
4197 PyFile_SetBufSize(p3, 0);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004198 f = Py_BuildValue("OOO",p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004199 Py_XDECREF(p1);
4200 Py_XDECREF(p2);
4201 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004202 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004203 break;
4204 }
4205 }
4206
4207 if (n == POPEN_4) {
4208 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004209 hChildStdinRd,
4210 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004211 hChildStdoutWr,
4212 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004213 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004214 }
4215 else {
4216 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004217 hChildStdinRd,
4218 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004219 hChildStderrWr,
4220 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004221 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004222 }
4223
Mark Hammondb37a3732000-08-14 04:47:33 +00004224 /*
4225 * Insert the files we've created into the process dictionary
4226 * all referencing the list with the process handle and the
4227 * initial number of files (see description below in _PyPclose).
4228 * Since if _PyPclose later tried to wait on a process when all
4229 * handles weren't closed, it could create a deadlock with the
4230 * child, we spend some energy here to try to ensure that we
4231 * either insert all file handles into the dictionary or none
4232 * at all. It's a little clumsy with the various popen modes
4233 * and variable number of files involved.
4234 */
4235 if (!_PyPopenProcs) {
4236 _PyPopenProcs = PyDict_New();
4237 }
4238
4239 if (_PyPopenProcs) {
4240 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4241 int ins_rc[3];
4242
4243 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4244 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4245
4246 procObj = PyList_New(2);
4247 hProcessObj = PyLong_FromVoidPtr(hProcess);
4248 intObj = PyInt_FromLong(file_count);
4249
4250 if (procObj && hProcessObj && intObj) {
4251 PyList_SetItem(procObj,0,hProcessObj);
4252 PyList_SetItem(procObj,1,intObj);
4253
4254 fileObj[0] = PyLong_FromVoidPtr(f1);
4255 if (fileObj[0]) {
4256 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4257 fileObj[0],
4258 procObj);
4259 }
4260 if (file_count >= 2) {
4261 fileObj[1] = PyLong_FromVoidPtr(f2);
4262 if (fileObj[1]) {
4263 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4264 fileObj[1],
4265 procObj);
4266 }
4267 }
4268 if (file_count >= 3) {
4269 fileObj[2] = PyLong_FromVoidPtr(f3);
4270 if (fileObj[2]) {
4271 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4272 fileObj[2],
4273 procObj);
4274 }
4275 }
4276
4277 if (ins_rc[0] < 0 || !fileObj[0] ||
4278 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4279 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4280 /* Something failed - remove any dictionary
4281 * entries that did make it.
4282 */
4283 if (!ins_rc[0] && fileObj[0]) {
4284 PyDict_DelItem(_PyPopenProcs,
4285 fileObj[0]);
4286 }
4287 if (!ins_rc[1] && fileObj[1]) {
4288 PyDict_DelItem(_PyPopenProcs,
4289 fileObj[1]);
4290 }
4291 if (!ins_rc[2] && fileObj[2]) {
4292 PyDict_DelItem(_PyPopenProcs,
4293 fileObj[2]);
4294 }
4295 }
4296 }
Tim Peters5aa91602002-01-30 05:46:57 +00004297
Mark Hammondb37a3732000-08-14 04:47:33 +00004298 /*
4299 * Clean up our localized references for the dictionary keys
4300 * and value since PyDict_SetItem will Py_INCREF any copies
4301 * that got placed in the dictionary.
4302 */
4303 Py_XDECREF(procObj);
4304 Py_XDECREF(fileObj[0]);
4305 Py_XDECREF(fileObj[1]);
4306 Py_XDECREF(fileObj[2]);
4307 }
4308
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004309 /* Child is launched. Close the parents copy of those pipe
4310 * handles that only the child should have open. You need to
4311 * make sure that no handles to the write end of the output pipe
4312 * are maintained in this process or else the pipe will not close
4313 * when the child process exits and the ReadFile will hang. */
4314
4315 if (!CloseHandle(hChildStdinRd))
4316 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004317
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004318 if (!CloseHandle(hChildStdoutWr))
4319 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004320
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004321 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4322 return win32_error("CloseHandle", NULL);
4323
4324 return f;
4325}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004326
4327/*
4328 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4329 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004330 *
4331 * This function uses the _PyPopenProcs dictionary in order to map the
4332 * input file pointer to information about the process that was
4333 * originally created by the popen* call that created the file pointer.
4334 * The dictionary uses the file pointer as a key (with one entry
4335 * inserted for each file returned by the original popen* call) and a
4336 * single list object as the value for all files from a single call.
4337 * The list object contains the Win32 process handle at [0], and a file
4338 * count at [1], which is initialized to the total number of file
4339 * handles using that list.
4340 *
4341 * This function closes whichever handle it is passed, and decrements
4342 * the file count in the dictionary for the process handle pointed to
4343 * by this file. On the last close (when the file count reaches zero),
4344 * this function will wait for the child process and then return its
4345 * exit code as the result of the close() operation. This permits the
4346 * files to be closed in any order - it is always the close() of the
4347 * final handle that will return the exit code.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004348 */
Tim Peters736aa322000-09-01 06:51:24 +00004349
4350 /* RED_FLAG 31-Aug-2000 Tim
4351 * This is always called (today!) between a pair of
4352 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
4353 * macros. So the thread running this has no valid thread state, as
4354 * far as Python is concerned. However, this calls some Python API
4355 * functions that cannot be called safely without a valid thread
4356 * state, in particular PyDict_GetItem.
4357 * As a temporary hack (although it may last for years ...), we
4358 * *rely* on not having a valid thread state in this function, in
4359 * order to create our own "from scratch".
4360 * This will deadlock if _PyPclose is ever called by a thread
4361 * holding the global lock.
4362 */
4363
Fredrik Lundh56055a42000-07-23 19:47:12 +00004364static int _PyPclose(FILE *file)
4365{
Fredrik Lundh20318932000-07-26 17:29:12 +00004366 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004367 DWORD exit_code;
4368 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004369 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4370 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004371#ifdef WITH_THREAD
4372 PyInterpreterState* pInterpreterState;
4373 PyThreadState* pThreadState;
4374#endif
4375
Fredrik Lundh20318932000-07-26 17:29:12 +00004376 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004377 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004378 */
4379 result = fclose(file);
4380
Tim Peters736aa322000-09-01 06:51:24 +00004381#ifdef WITH_THREAD
4382 /* Bootstrap a valid thread state into existence. */
4383 pInterpreterState = PyInterpreterState_New();
4384 if (!pInterpreterState) {
4385 /* Well, we're hosed now! We don't have a thread
4386 * state, so can't call a nice error routine, or raise
4387 * an exception. Just die.
4388 */
4389 Py_FatalError("unable to allocate interpreter state "
Fred Drake661ea262000-10-24 19:57:45 +00004390 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004391 return -1; /* unreachable */
4392 }
4393 pThreadState = PyThreadState_New(pInterpreterState);
4394 if (!pThreadState) {
4395 Py_FatalError("unable to allocate thread state "
Fred Drake661ea262000-10-24 19:57:45 +00004396 "when closing popen object");
Tim Peters736aa322000-09-01 06:51:24 +00004397 return -1; /* unreachable */
4398 }
4399 /* Grab the global lock. Note that this will deadlock if the
4400 * current thread already has the lock! (see RED_FLAG comments
4401 * before this function)
4402 */
4403 PyEval_RestoreThread(pThreadState);
4404#endif
4405
Fredrik Lundh56055a42000-07-23 19:47:12 +00004406 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004407 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4408 (procObj = PyDict_GetItem(_PyPopenProcs,
4409 fileObj)) != NULL &&
4410 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4411 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4412
4413 hProcess = PyLong_AsVoidPtr(hProcessObj);
4414 file_count = PyInt_AsLong(intObj);
4415
4416 if (file_count > 1) {
4417 /* Still other files referencing process */
4418 file_count--;
4419 PyList_SetItem(procObj,1,
4420 PyInt_FromLong(file_count));
4421 } else {
4422 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004423 if (result != EOF &&
4424 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4425 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004426 /* Possible truncation here in 16-bit environments, but
4427 * real exit codes are just the lower byte in any event.
4428 */
4429 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004430 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004431 /* Indicate failure - this will cause the file object
4432 * to raise an I/O error and translate the last Win32
4433 * error code from errno. We do have a problem with
4434 * last errors that overlap the normal errno table,
4435 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004436 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004437 if (result != EOF) {
4438 /* If the error wasn't from the fclose(), then
4439 * set errno for the file object error handling.
4440 */
4441 errno = GetLastError();
4442 }
4443 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004444 }
4445
4446 /* Free up the native handle at this point */
4447 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004448 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004449
Mark Hammondb37a3732000-08-14 04:47:33 +00004450 /* Remove this file pointer from dictionary */
4451 PyDict_DelItem(_PyPopenProcs, fileObj);
4452
4453 if (PyDict_Size(_PyPopenProcs) == 0) {
4454 Py_DECREF(_PyPopenProcs);
4455 _PyPopenProcs = NULL;
4456 }
4457
4458 } /* if object retrieval ok */
4459
4460 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004461 } /* if _PyPopenProcs */
4462
Tim Peters736aa322000-09-01 06:51:24 +00004463#ifdef WITH_THREAD
4464 /* Tear down the thread & interpreter states.
4465 * Note that interpreter state clear & delete functions automatically
Tim Peters9acdd3a2000-09-01 19:26:36 +00004466 * call the thread clear & delete functions, and indeed insist on
4467 * doing that themselves. The lock must be held during the clear, but
4468 * need not be held during the delete.
Tim Peters736aa322000-09-01 06:51:24 +00004469 */
4470 PyInterpreterState_Clear(pInterpreterState);
4471 PyEval_ReleaseThread(pThreadState);
4472 PyInterpreterState_Delete(pInterpreterState);
4473#endif
4474
Fredrik Lundh56055a42000-07-23 19:47:12 +00004475 return result;
4476}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004477
4478#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004479static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004480posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004481{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004482 char *name;
4483 char *mode = "r";
4484 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004485 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004486 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004487 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004488 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004489 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004490 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004491 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004492 if (fp == NULL)
4493 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004494 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004495 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004496 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004497 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004498}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004499
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004500#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004501#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004503
Guido van Rossumb6775db1994-08-01 11:34:53 +00004504#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004505PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004506"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004507Set the current process's user id.");
4508
Barry Warsaw53699e91996-12-10 23:23:01 +00004509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004510posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004511{
4512 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004513 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004514 return NULL;
4515 if (setuid(uid) < 0)
4516 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004517 Py_INCREF(Py_None);
4518 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004519}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004520#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004521
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004522
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004523#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004524PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004525"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004526Set the current process's effective user id.");
4527
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004528static PyObject *
4529posix_seteuid (PyObject *self, PyObject *args)
4530{
4531 int euid;
4532 if (!PyArg_ParseTuple(args, "i", &euid)) {
4533 return NULL;
4534 } else if (seteuid(euid) < 0) {
4535 return posix_error();
4536 } else {
4537 Py_INCREF(Py_None);
4538 return Py_None;
4539 }
4540}
4541#endif /* HAVE_SETEUID */
4542
4543#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004544PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004545"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004546Set the current process's effective group id.");
4547
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004548static PyObject *
4549posix_setegid (PyObject *self, PyObject *args)
4550{
4551 int egid;
4552 if (!PyArg_ParseTuple(args, "i", &egid)) {
4553 return NULL;
4554 } else if (setegid(egid) < 0) {
4555 return posix_error();
4556 } else {
4557 Py_INCREF(Py_None);
4558 return Py_None;
4559 }
4560}
4561#endif /* HAVE_SETEGID */
4562
4563#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004564PyDoc_STRVAR(posix_setreuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004565"seteuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004566Set the current process's real and effective user ids.");
4567
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004568static PyObject *
4569posix_setreuid (PyObject *self, PyObject *args)
4570{
4571 int ruid, euid;
4572 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4573 return NULL;
4574 } else if (setreuid(ruid, euid) < 0) {
4575 return posix_error();
4576 } else {
4577 Py_INCREF(Py_None);
4578 return Py_None;
4579 }
4580}
4581#endif /* HAVE_SETREUID */
4582
4583#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004584PyDoc_STRVAR(posix_setregid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004585"setegid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004586Set the current process's real and effective group ids.");
4587
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004588static PyObject *
4589posix_setregid (PyObject *self, PyObject *args)
4590{
4591 int rgid, egid;
4592 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4593 return NULL;
4594 } else if (setregid(rgid, egid) < 0) {
4595 return posix_error();
4596 } else {
4597 Py_INCREF(Py_None);
4598 return Py_None;
4599 }
4600}
4601#endif /* HAVE_SETREGID */
4602
Guido van Rossumb6775db1994-08-01 11:34:53 +00004603#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004604PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004605"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004606Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004607
Barry Warsaw53699e91996-12-10 23:23:01 +00004608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004609posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004610{
4611 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004612 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004613 return NULL;
4614 if (setgid(gid) < 0)
4615 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004616 Py_INCREF(Py_None);
4617 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004618}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004619#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004620
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004621#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004622PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004623"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004624Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004625
4626static PyObject *
4627posix_setgroups(PyObject *self, PyObject *args)
4628{
4629 PyObject *groups;
4630 int i, len;
4631 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004632
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004633 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4634 return NULL;
4635 if (!PySequence_Check(groups)) {
4636 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4637 return NULL;
4638 }
4639 len = PySequence_Size(groups);
4640 if (len > MAX_GROUPS) {
4641 PyErr_SetString(PyExc_ValueError, "too many groups");
4642 return NULL;
4643 }
4644 for(i = 0; i < len; i++) {
4645 PyObject *elem;
4646 elem = PySequence_GetItem(groups, i);
4647 if (!elem)
4648 return NULL;
4649 if (!PyInt_Check(elem)) {
4650 PyErr_SetString(PyExc_TypeError,
4651 "groups must be integers");
4652 Py_DECREF(elem);
4653 return NULL;
4654 }
4655 /* XXX: check that value fits into gid_t. */
4656 grouplist[i] = PyInt_AsLong(elem);
4657 Py_DECREF(elem);
4658 }
4659
4660 if (setgroups(len, grouplist) < 0)
4661 return posix_error();
4662 Py_INCREF(Py_None);
4663 return Py_None;
4664}
4665#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004666
Guido van Rossumb6775db1994-08-01 11:34:53 +00004667#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004668PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004669"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004670Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004671
Barry Warsaw53699e91996-12-10 23:23:01 +00004672static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004673posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004674{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004675 int pid, options;
4676#ifdef UNION_WAIT
4677 union wait status;
4678#define status_i (status.w_status)
4679#else
4680 int status;
4681#define status_i status
4682#endif
4683 status_i = 0;
4684
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004685 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004686 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004687 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004688 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004689 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004690 if (pid == -1)
4691 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004692 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004693 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004694}
4695
Tim Petersab034fa2002-02-01 11:27:43 +00004696#elif defined(HAVE_CWAIT)
4697
4698/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004699PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004700"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004701"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004702
4703static PyObject *
4704posix_waitpid(PyObject *self, PyObject *args)
4705{
4706 int pid, options;
4707 int status;
4708
4709 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4710 return NULL;
4711 Py_BEGIN_ALLOW_THREADS
4712 pid = _cwait(&status, pid, options);
4713 Py_END_ALLOW_THREADS
4714 if (pid == -1)
4715 return posix_error();
4716 else
4717 /* shift the status left a byte so this is more like the
4718 POSIX waitpid */
4719 return Py_BuildValue("ii", pid, status << 8);
4720}
4721#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004722
Guido van Rossumad0ee831995-03-01 10:34:45 +00004723#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004724PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004725"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004726Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004727
Barry Warsaw53699e91996-12-10 23:23:01 +00004728static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004729posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004730{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004731 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004732#ifdef UNION_WAIT
4733 union wait status;
4734#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004735#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004736 int status;
4737#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004738#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004739
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004740 status_i = 0;
4741 Py_BEGIN_ALLOW_THREADS
4742 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004743 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004744 if (pid == -1)
4745 return posix_error();
4746 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004747 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004748#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004749}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004750#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004751
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004752
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004753PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004754"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004755Like stat(path), but do not follow symbolic links.");
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_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004759{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004760#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004761 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004762#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004763#ifdef MS_WINDOWS
4764 return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64);
4765#else
4766 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4767#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004768#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004769}
4770
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004771
Guido van Rossumb6775db1994-08-01 11:34:53 +00004772#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004773PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004774"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004775Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004776
Barry Warsaw53699e91996-12-10 23:23:01 +00004777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004778posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004779{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004780 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004781 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004782 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004783 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004784 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004785 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004786 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004787 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004788 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004789 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004790 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004791}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004792#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004793
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004794
Guido van Rossumb6775db1994-08-01 11:34:53 +00004795#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004796PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004797"symlink(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004798Create a symbolic link.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004799
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004800static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004801posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004802{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004803 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004804}
4805#endif /* HAVE_SYMLINK */
4806
4807
4808#ifdef HAVE_TIMES
4809#ifndef HZ
4810#define HZ 60 /* Universal constant :-) */
4811#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00004812
Guido van Rossumd48f2521997-12-05 22:19:34 +00004813#if defined(PYCC_VACPP) && defined(PYOS_OS2)
4814static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00004815system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004816{
4817 ULONG value = 0;
4818
4819 Py_BEGIN_ALLOW_THREADS
4820 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
4821 Py_END_ALLOW_THREADS
4822
4823 return value;
4824}
4825
4826static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004827posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00004828{
Guido van Rossumd48f2521997-12-05 22:19:34 +00004829 /* Currently Only Uptime is Provided -- Others Later */
4830 return Py_BuildValue("ddddd",
4831 (double)0 /* t.tms_utime / HZ */,
4832 (double)0 /* t.tms_stime / HZ */,
4833 (double)0 /* t.tms_cutime / HZ */,
4834 (double)0 /* t.tms_cstime / HZ */,
4835 (double)system_uptime() / 1000);
4836}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004837#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004838static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004839posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00004840{
4841 struct tms t;
4842 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00004843 errno = 0;
4844 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00004845 if (c == (clock_t) -1)
4846 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004847 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00004848 (double)t.tms_utime / HZ,
4849 (double)t.tms_stime / HZ,
4850 (double)t.tms_cutime / HZ,
4851 (double)t.tms_cstime / HZ,
4852 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00004853}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004854#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00004855#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004856
4857
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004858#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004859#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00004860static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004861posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004862{
4863 FILETIME create, exit, kernel, user;
4864 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004865 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004866 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
4867 /* The fields of a FILETIME structure are the hi and lo part
4868 of a 64-bit value expressed in 100 nanosecond units.
4869 1e7 is one second in such units; 1e-7 the inverse.
4870 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
4871 */
Barry Warsaw53699e91996-12-10 23:23:01 +00004872 return Py_BuildValue(
4873 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00004874 (double)(kernel.dwHighDateTime*429.4967296 +
4875 kernel.dwLowDateTime*1e-7),
4876 (double)(user.dwHighDateTime*429.4967296 +
4877 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00004878 (double)0,
4879 (double)0,
4880 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004881}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004882#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004883
4884#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004885PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004886"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004887Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00004888#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00004889
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004890
Guido van Rossumb6775db1994-08-01 11:34:53 +00004891#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004892PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004893"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004894Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004895
Barry Warsaw53699e91996-12-10 23:23:01 +00004896static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004897posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004898{
Guido van Rossum687dd131993-05-17 08:34:16 +00004899 if (setsid() < 0)
4900 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004901 Py_INCREF(Py_None);
4902 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004903}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004904#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004905
Guido van Rossumb6775db1994-08-01 11:34:53 +00004906#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004907PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004908"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004910
Barry Warsaw53699e91996-12-10 23:23:01 +00004911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004912posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00004913{
4914 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004915 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00004916 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004917 if (setpgid(pid, pgrp) < 0)
4918 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004919 Py_INCREF(Py_None);
4920 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00004921}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004922#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00004923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004924
Guido van Rossumb6775db1994-08-01 11:34:53 +00004925#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004926PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004927"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004928Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004929
Barry Warsaw53699e91996-12-10 23:23:01 +00004930static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004931posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004932{
4933 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004934 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004935 return NULL;
4936 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00004937 if (pgid < 0)
4938 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004939 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00004940}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004941#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00004942
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004943
Guido van Rossumb6775db1994-08-01 11:34:53 +00004944#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004945PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004946"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004947Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004948
Barry Warsaw53699e91996-12-10 23:23:01 +00004949static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004950posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00004951{
4952 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004953 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00004954 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004955 if (tcsetpgrp(fd, pgid) < 0)
4956 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00004957 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00004958 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00004959}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004960#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00004961
Guido van Rossum687dd131993-05-17 08:34:16 +00004962/* Functions acting on file descriptors */
4963
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004964PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004965"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004966Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004967
Barry Warsaw53699e91996-12-10 23:23:01 +00004968static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004969posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00004970{
Mark Hammondef8b6542001-05-13 08:04:26 +00004971 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00004972 int flag;
4973 int mode = 0777;
4974 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004975
4976#ifdef MS_WINDOWS
4977 if (unicode_file_names()) {
4978 PyUnicodeObject *po;
4979 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
4980 Py_BEGIN_ALLOW_THREADS
4981 /* PyUnicode_AS_UNICODE OK without thread
4982 lock as it is a simple dereference. */
4983 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
4984 Py_END_ALLOW_THREADS
4985 if (fd < 0)
4986 return posix_error();
4987 return PyInt_FromLong((long)fd);
4988 }
4989 /* Drop the argument parsing error as narrow strings
4990 are also valid. */
4991 PyErr_Clear();
4992 }
4993#endif
4994
Tim Peters5aa91602002-01-30 05:46:57 +00004995 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00004996 Py_FileSystemDefaultEncoding, &file,
4997 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00004998 return NULL;
4999
Barry Warsaw53699e91996-12-10 23:23:01 +00005000 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005001 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005002 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005003 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005004 return posix_error_with_allocated_filename(file);
5005 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005006 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005007}
5008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005009
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005010PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005011"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005012Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005013
Barry Warsaw53699e91996-12-10 23:23:01 +00005014static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005015posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005016{
5017 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005018 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005019 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005020 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005021 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005022 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005023 if (res < 0)
5024 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005025 Py_INCREF(Py_None);
5026 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005027}
5028
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005029
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005030PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005031"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005032Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005033
Barry Warsaw53699e91996-12-10 23:23:01 +00005034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005035posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005036{
5037 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005038 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005039 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005040 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005041 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005042 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005043 if (fd < 0)
5044 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005045 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005046}
5047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005048
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005049PyDoc_STRVAR(posix_dup2__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005050"dup2(fd, fd2)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005051Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005052
Barry Warsaw53699e91996-12-10 23:23:01 +00005053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005054posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005055{
5056 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005057 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005058 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005059 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005060 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005061 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005062 if (res < 0)
5063 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005064 Py_INCREF(Py_None);
5065 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005066}
5067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005068
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005069PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005070"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005071Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005072
Barry Warsaw53699e91996-12-10 23:23:01 +00005073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005074posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005075{
5076 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005077#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005078 LONG_LONG pos, res;
5079#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005080 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005081#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005082 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005083 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005084 return NULL;
5085#ifdef SEEK_SET
5086 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5087 switch (how) {
5088 case 0: how = SEEK_SET; break;
5089 case 1: how = SEEK_CUR; break;
5090 case 2: how = SEEK_END; break;
5091 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005092#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005093
5094#if !defined(HAVE_LARGEFILE_SUPPORT)
5095 pos = PyInt_AsLong(posobj);
5096#else
5097 pos = PyLong_Check(posobj) ?
5098 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5099#endif
5100 if (PyErr_Occurred())
5101 return NULL;
5102
Barry Warsaw53699e91996-12-10 23:23:01 +00005103 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005104#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005105 res = _lseeki64(fd, pos, how);
5106#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005107 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005108#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005109 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005110 if (res < 0)
5111 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005112
5113#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005114 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005115#else
5116 return PyLong_FromLongLong(res);
5117#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005118}
5119
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005120
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005121PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005122"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005123Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005124
Barry Warsaw53699e91996-12-10 23:23:01 +00005125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005126posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005127{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005128 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005129 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005130 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005131 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005132 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005133 if (buffer == NULL)
5134 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005135 Py_BEGIN_ALLOW_THREADS
5136 n = read(fd, PyString_AsString(buffer), size);
5137 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005138 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005139 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005140 return posix_error();
5141 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005142 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005143 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005144 return buffer;
5145}
5146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005147
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005148PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005149"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005150Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005151
Barry Warsaw53699e91996-12-10 23:23:01 +00005152static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005153posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005154{
5155 int fd, size;
5156 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005157 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005158 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005159 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005160 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005161 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005162 if (size < 0)
5163 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005164 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005165}
5166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005168PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005169"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005170Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005171
Barry Warsaw53699e91996-12-10 23:23:01 +00005172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005173posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005174{
5175 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005176 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005177 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005178 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005179 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005180#ifdef __VMS
5181 /* on OpenVMS we must ensure that all bytes are written to the file */
5182 fsync(fd);
5183#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005184 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005185 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005186 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005187 if (res != 0)
5188 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005189
Fred Drake699f3522000-06-29 21:12:41 +00005190 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005191}
5192
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005194PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005195"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005196Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005197
Barry Warsaw53699e91996-12-10 23:23:01 +00005198static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005199posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005200{
Guido van Rossum687dd131993-05-17 08:34:16 +00005201 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005202 char *mode = "r";
5203 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005204 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005205 PyObject *f;
5206 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005207 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005208
Thomas Heller1f043e22002-11-07 16:00:59 +00005209 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5210 PyErr_Format(PyExc_ValueError,
5211 "invalid file mode '%s'", mode);
5212 return NULL;
5213 }
5214
Barry Warsaw53699e91996-12-10 23:23:01 +00005215 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005216 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005217 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005218 if (fp == NULL)
5219 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005220 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005221 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005222 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005223 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005224}
5225
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005226PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005227"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005228Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005229connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005230
5231static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005232posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005233{
5234 int fd;
5235 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5236 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005237 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005238}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005239
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005240#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005241PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005242"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005243Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005244
Barry Warsaw53699e91996-12-10 23:23:01 +00005245static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005246posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005247{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005248#if defined(PYOS_OS2)
5249 HFILE read, write;
5250 APIRET rc;
5251
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005252 Py_BEGIN_ALLOW_THREADS
5253 rc = DosCreatePipe( &read, &write, 4096);
5254 Py_END_ALLOW_THREADS
5255 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005256 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005257
5258 return Py_BuildValue("(ii)", read, write);
5259#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005260#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005261 int fds[2];
5262 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005263 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005264#if defined(__VMS)
5265 res = pipe(fds,0,2100); /* bigger mailbox quota than 512 */
5266#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005267 res = pipe(fds);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00005268#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005269 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005270 if (res != 0)
5271 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005272 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005273#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005274 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005275 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005276 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005277 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005278 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005279 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005280 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005281 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005282 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5283 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005284 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005285#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005286#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005287}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005288#endif /* HAVE_PIPE */
5289
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005290
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005291#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005292PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005293"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005294Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005295
Barry Warsaw53699e91996-12-10 23:23:01 +00005296static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005297posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005298{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005299 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005300 int mode = 0666;
5301 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005302 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005303 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005304 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005305 res = mkfifo(filename, mode);
5306 Py_END_ALLOW_THREADS
5307 if (res < 0)
5308 return posix_error();
5309 Py_INCREF(Py_None);
5310 return Py_None;
5311}
5312#endif
5313
5314
Neal Norwitz11690112002-07-30 01:08:28 +00005315#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005316PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005317"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005318Create a filesystem node (file, device special file or named pipe)\n\
5319named filename. mode specifies both the permissions to use and the\n\
5320type of node to be created, being combined (bitwise OR) with one of\n\
5321S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005322device defines the newly created device special file (probably using\n\
5323os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005324
5325
5326static PyObject *
5327posix_mknod(PyObject *self, PyObject *args)
5328{
5329 char *filename;
5330 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005331 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005332 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005333 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005334 return NULL;
5335 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005336 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005337 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005338 if (res < 0)
5339 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005340 Py_INCREF(Py_None);
5341 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005342}
5343#endif
5344
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005345#ifdef HAVE_DEVICE_MACROS
5346PyDoc_STRVAR(posix_major__doc__,
5347"major(device) -> major number\n\
5348Extracts a device major number from a raw device number.");
5349
5350static PyObject *
5351posix_major(PyObject *self, PyObject *args)
5352{
5353 int device;
5354 if (!PyArg_ParseTuple(args, "i:major", &device))
5355 return NULL;
5356 return PyInt_FromLong((long)major(device));
5357}
5358
5359PyDoc_STRVAR(posix_minor__doc__,
5360"minor(device) -> minor number\n\
5361Extracts a device minor number from a raw device number.");
5362
5363static PyObject *
5364posix_minor(PyObject *self, PyObject *args)
5365{
5366 int device;
5367 if (!PyArg_ParseTuple(args, "i:minor", &device))
5368 return NULL;
5369 return PyInt_FromLong((long)minor(device));
5370}
5371
5372PyDoc_STRVAR(posix_makedev__doc__,
5373"makedev(major, minor) -> device number\n\
5374Composes a raw device number from the major and minor device numbers.");
5375
5376static PyObject *
5377posix_makedev(PyObject *self, PyObject *args)
5378{
5379 int major, minor;
5380 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5381 return NULL;
5382 return PyInt_FromLong((long)makedev(major, minor));
5383}
5384#endif /* device macros */
5385
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005386
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005387#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005388PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005389"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005390Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005391
Barry Warsaw53699e91996-12-10 23:23:01 +00005392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005393posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005394{
5395 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005396 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005397 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005398 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005399
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005400 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005401 return NULL;
5402
5403#if !defined(HAVE_LARGEFILE_SUPPORT)
5404 length = PyInt_AsLong(lenobj);
5405#else
5406 length = PyLong_Check(lenobj) ?
5407 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5408#endif
5409 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005410 return NULL;
5411
Barry Warsaw53699e91996-12-10 23:23:01 +00005412 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005413 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005414 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005415 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005416 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005417 return NULL;
5418 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005419 Py_INCREF(Py_None);
5420 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005421}
5422#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005423
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005424#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005425PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005426"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005427Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005428
Fred Drake762e2061999-08-26 17:23:54 +00005429/* Save putenv() parameters as values here, so we can collect them when they
5430 * get re-set with another call for the same key. */
5431static PyObject *posix_putenv_garbage;
5432
Tim Peters5aa91602002-01-30 05:46:57 +00005433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005434posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005435{
5436 char *s1, *s2;
5437 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005438 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005439 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005440
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005441 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005442 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005443
5444#if defined(PYOS_OS2)
5445 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5446 APIRET rc;
5447
5448 if (strlen(s2) == 0) /* If New Value is an Empty String */
5449 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5450
5451 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5452 if (rc != NO_ERROR)
5453 return os2_error(rc);
5454
5455 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5456 APIRET rc;
5457
5458 if (strlen(s2) == 0) /* If New Value is an Empty String */
5459 s2 = NULL; /* Then OS/2 API Wants a NULL to Undefine It */
5460
5461 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5462 if (rc != NO_ERROR)
5463 return os2_error(rc);
5464 } else {
5465#endif
5466
Fred Drake762e2061999-08-26 17:23:54 +00005467 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005468 len = strlen(s1) + strlen(s2) + 2;
5469 /* len includes space for a trailing \0; the size arg to
5470 PyString_FromStringAndSize does not count that */
5471 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005472 if (newstr == NULL)
5473 return PyErr_NoMemory();
5474 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005475 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005476 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005477 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005478 posix_error();
5479 return NULL;
5480 }
Fred Drake762e2061999-08-26 17:23:54 +00005481 /* Install the first arg and newstr in posix_putenv_garbage;
5482 * this will cause previous value to be collected. This has to
5483 * happen after the real putenv() call because the old value
5484 * was still accessible until then. */
5485 if (PyDict_SetItem(posix_putenv_garbage,
5486 PyTuple_GET_ITEM(args, 0), newstr)) {
5487 /* really not much we can do; just leak */
5488 PyErr_Clear();
5489 }
5490 else {
5491 Py_DECREF(newstr);
5492 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005493
5494#if defined(PYOS_OS2)
5495 }
5496#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005497 Py_INCREF(Py_None);
5498 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005499}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005500#endif /* putenv */
5501
Guido van Rossumc524d952001-10-19 01:31:59 +00005502#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005503PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005504"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005505Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005506
5507static PyObject *
5508posix_unsetenv(PyObject *self, PyObject *args)
5509{
5510 char *s1;
5511
5512 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5513 return NULL;
5514
5515 unsetenv(s1);
5516
5517 /* Remove the key from posix_putenv_garbage;
5518 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005519 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005520 * old value was still accessible until then.
5521 */
5522 if (PyDict_DelItem(posix_putenv_garbage,
5523 PyTuple_GET_ITEM(args, 0))) {
5524 /* really not much we can do; just leak */
5525 PyErr_Clear();
5526 }
5527
5528 Py_INCREF(Py_None);
5529 return Py_None;
5530}
5531#endif /* unsetenv */
5532
Guido van Rossumb6a47161997-09-15 22:54:34 +00005533#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005534PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005535"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005536Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005537
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005539posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005540{
5541 int code;
5542 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005543 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005544 return NULL;
5545 message = strerror(code);
5546 if (message == NULL) {
5547 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005548 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005549 return NULL;
5550 }
5551 return PyString_FromString(message);
5552}
5553#endif /* strerror */
5554
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005555
Guido van Rossumc9641791998-08-04 15:26:23 +00005556#ifdef HAVE_SYS_WAIT_H
5557
Fred Drake106c1a02002-04-23 15:58:02 +00005558#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005559PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005560"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005561Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005562
5563static PyObject *
5564posix_WCOREDUMP(PyObject *self, PyObject *args)
5565{
5566#ifdef UNION_WAIT
5567 union wait status;
5568#define status_i (status.w_status)
5569#else
5570 int status;
5571#define status_i status
5572#endif
5573 status_i = 0;
5574
5575 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5576 {
5577 return NULL;
5578 }
5579
5580 return PyBool_FromLong(WCOREDUMP(status));
5581#undef status_i
5582}
5583#endif /* WCOREDUMP */
5584
5585#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005586PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005587"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005588Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005589job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005590
5591static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005592posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005593{
5594#ifdef UNION_WAIT
5595 union wait status;
5596#define status_i (status.w_status)
5597#else
5598 int status;
5599#define status_i status
5600#endif
5601 status_i = 0;
5602
5603 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5604 {
5605 return NULL;
5606 }
5607
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005608 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005609#undef status_i
5610}
5611#endif /* WIFCONTINUED */
5612
Guido van Rossumc9641791998-08-04 15:26:23 +00005613#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005614PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005615"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005616Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005617
5618static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005619posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005620{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005621#ifdef UNION_WAIT
5622 union wait status;
5623#define status_i (status.w_status)
5624#else
5625 int status;
5626#define status_i status
5627#endif
5628 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005629
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005630 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005631 {
5632 return NULL;
5633 }
Tim Peters5aa91602002-01-30 05:46:57 +00005634
Fred Drake106c1a02002-04-23 15:58:02 +00005635 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005636#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005637}
5638#endif /* WIFSTOPPED */
5639
5640#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005641PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005642"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005643Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005644
5645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005646posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005647{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005648#ifdef UNION_WAIT
5649 union wait status;
5650#define status_i (status.w_status)
5651#else
5652 int status;
5653#define status_i status
5654#endif
5655 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005656
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005657 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005658 {
5659 return NULL;
5660 }
Tim Peters5aa91602002-01-30 05:46:57 +00005661
Fred Drake106c1a02002-04-23 15:58:02 +00005662 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005663#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005664}
5665#endif /* WIFSIGNALED */
5666
5667#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005668PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005669"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005670Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005671system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005672
5673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005674posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005675{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005676#ifdef UNION_WAIT
5677 union wait status;
5678#define status_i (status.w_status)
5679#else
5680 int status;
5681#define status_i status
5682#endif
5683 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005684
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005685 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005686 {
5687 return NULL;
5688 }
Tim Peters5aa91602002-01-30 05:46:57 +00005689
Fred Drake106c1a02002-04-23 15:58:02 +00005690 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005691#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005692}
5693#endif /* WIFEXITED */
5694
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005695#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005696PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005697"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005698Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005699
5700static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005701posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005702{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005703#ifdef UNION_WAIT
5704 union wait status;
5705#define status_i (status.w_status)
5706#else
5707 int status;
5708#define status_i status
5709#endif
5710 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005711
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005712 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005713 {
5714 return NULL;
5715 }
Tim Peters5aa91602002-01-30 05:46:57 +00005716
Guido van Rossumc9641791998-08-04 15:26:23 +00005717 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005718#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005719}
5720#endif /* WEXITSTATUS */
5721
5722#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005723PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005724"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005725Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005726value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005727
5728static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005729posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005730{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005731#ifdef UNION_WAIT
5732 union wait status;
5733#define status_i (status.w_status)
5734#else
5735 int status;
5736#define status_i status
5737#endif
5738 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005739
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005740 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005741 {
5742 return NULL;
5743 }
Tim Peters5aa91602002-01-30 05:46:57 +00005744
Guido van Rossumc9641791998-08-04 15:26:23 +00005745 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005746#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005747}
5748#endif /* WTERMSIG */
5749
5750#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005751PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005752"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005753Return the signal that stopped the process that provided\n\
5754the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005755
5756static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005757posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005758{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005759#ifdef UNION_WAIT
5760 union wait status;
5761#define status_i (status.w_status)
5762#else
5763 int status;
5764#define status_i status
5765#endif
5766 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005767
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005768 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005769 {
5770 return NULL;
5771 }
Tim Peters5aa91602002-01-30 05:46:57 +00005772
Guido van Rossumc9641791998-08-04 15:26:23 +00005773 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005774#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005775}
5776#endif /* WSTOPSIG */
5777
5778#endif /* HAVE_SYS_WAIT_H */
5779
5780
Guido van Rossum94f6f721999-01-06 18:42:14 +00005781#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005782#ifdef _SCO_DS
5783/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5784 needed definitions in sys/statvfs.h */
5785#define _SVID3
5786#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005787#include <sys/statvfs.h>
5788
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005789static PyObject*
5790_pystatvfs_fromstructstatvfs(struct statvfs st) {
5791 PyObject *v = PyStructSequence_New(&StatVFSResultType);
5792 if (v == NULL)
5793 return NULL;
5794
5795#if !defined(HAVE_LARGEFILE_SUPPORT)
5796 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5797 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
5798 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
5799 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
5800 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
5801 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
5802 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
5803 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
5804 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5805 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5806#else
5807 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
5808 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00005809 PyStructSequence_SET_ITEM(v, 2,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005810 PyLong_FromLongLong((LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00005811 PyStructSequence_SET_ITEM(v, 3,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005812 PyLong_FromLongLong((LONG_LONG) st.f_bfree));
5813 PyStructSequence_SET_ITEM(v, 4,
5814 PyLong_FromLongLong((LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00005815 PyStructSequence_SET_ITEM(v, 5,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005816 PyLong_FromLongLong((LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00005817 PyStructSequence_SET_ITEM(v, 6,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005818 PyLong_FromLongLong((LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00005819 PyStructSequence_SET_ITEM(v, 7,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005820 PyLong_FromLongLong((LONG_LONG) st.f_favail));
5821 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
5822 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
5823#endif
5824
5825 return v;
5826}
5827
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005828PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005829"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005830Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005831
5832static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005833posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005834{
5835 int fd, res;
5836 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005837
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005838 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005839 return NULL;
5840 Py_BEGIN_ALLOW_THREADS
5841 res = fstatvfs(fd, &st);
5842 Py_END_ALLOW_THREADS
5843 if (res != 0)
5844 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005845
5846 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005847}
5848#endif /* HAVE_FSTATVFS */
5849
5850
5851#if defined(HAVE_STATVFS)
5852#include <sys/statvfs.h>
5853
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005854PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005855"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005856Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00005857
5858static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005859posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00005860{
5861 char *path;
5862 int res;
5863 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005864 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005865 return NULL;
5866 Py_BEGIN_ALLOW_THREADS
5867 res = statvfs(path, &st);
5868 Py_END_ALLOW_THREADS
5869 if (res != 0)
5870 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00005871
5872 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005873}
5874#endif /* HAVE_STATVFS */
5875
5876
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005877#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005878PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005879"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005880Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00005881The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005882or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005883
5884static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005885posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005886{
5887 PyObject *result = NULL;
5888 char *dir = NULL;
5889 char *pfx = NULL;
5890 char *name;
5891
5892 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
5893 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00005894
5895 if (PyErr_Warn(PyExc_RuntimeWarning,
5896 "tempnam is a potential security risk to your program") < 0)
5897 return NULL;
5898
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005899#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00005900 name = _tempnam(dir, pfx);
5901#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005902 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00005903#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005904 if (name == NULL)
5905 return PyErr_NoMemory();
5906 result = PyString_FromString(name);
5907 free(name);
5908 return result;
5909}
Guido van Rossumd371ff11999-01-25 16:12:23 +00005910#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005911
5912
5913#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005914PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005915"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005916Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005917
5918static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005919posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005920{
5921 FILE *fp;
5922
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005923 fp = tmpfile();
5924 if (fp == NULL)
5925 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00005926 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005927}
5928#endif
5929
5930
5931#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005932PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005933"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005934Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005935
5936static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005937posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005938{
5939 char buffer[L_tmpnam];
5940 char *name;
5941
Skip Montanaro95618b52001-08-18 18:52:10 +00005942 if (PyErr_Warn(PyExc_RuntimeWarning,
5943 "tmpnam is a potential security risk to your program") < 0)
5944 return NULL;
5945
Greg Wardb48bc172000-03-01 21:51:56 +00005946#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005947 name = tmpnam_r(buffer);
5948#else
5949 name = tmpnam(buffer);
5950#endif
5951 if (name == NULL) {
5952 PyErr_SetObject(PyExc_OSError,
5953 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00005954#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005955 "unexpected NULL from tmpnam_r"
5956#else
5957 "unexpected NULL from tmpnam"
5958#endif
5959 ));
5960 return NULL;
5961 }
5962 return PyString_FromString(buffer);
5963}
5964#endif
5965
5966
Fred Drakec9680921999-12-13 16:37:25 +00005967/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
5968 * It maps strings representing configuration variable names to
5969 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00005970 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00005971 * rarely-used constants. There are three separate tables that use
5972 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00005973 *
5974 * This code is always included, even if none of the interfaces that
5975 * need it are included. The #if hackery needed to avoid it would be
5976 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00005977 */
5978struct constdef {
5979 char *name;
5980 long value;
5981};
5982
Fred Drake12c6e2d1999-12-14 21:25:03 +00005983static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005984conv_confname(PyObject *arg, int *valuep, struct constdef *table,
5985 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00005986{
5987 if (PyInt_Check(arg)) {
5988 *valuep = PyInt_AS_LONG(arg);
5989 return 1;
5990 }
5991 if (PyString_Check(arg)) {
5992 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00005993 size_t lo = 0;
5994 size_t mid;
5995 size_t hi = tablesize;
5996 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00005997 char *confname = PyString_AS_STRING(arg);
5998 while (lo < hi) {
5999 mid = (lo + hi) / 2;
6000 cmp = strcmp(confname, table[mid].name);
6001 if (cmp < 0)
6002 hi = mid;
6003 else if (cmp > 0)
6004 lo = mid + 1;
6005 else {
6006 *valuep = table[mid].value;
6007 return 1;
6008 }
6009 }
6010 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6011 }
6012 else
6013 PyErr_SetString(PyExc_TypeError,
6014 "configuration names must be strings or integers");
6015 return 0;
6016}
6017
6018
6019#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6020static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006021#ifdef _PC_ABI_AIO_XFER_MAX
6022 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6023#endif
6024#ifdef _PC_ABI_ASYNC_IO
6025 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6026#endif
Fred Drakec9680921999-12-13 16:37:25 +00006027#ifdef _PC_ASYNC_IO
6028 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6029#endif
6030#ifdef _PC_CHOWN_RESTRICTED
6031 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6032#endif
6033#ifdef _PC_FILESIZEBITS
6034 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6035#endif
6036#ifdef _PC_LAST
6037 {"PC_LAST", _PC_LAST},
6038#endif
6039#ifdef _PC_LINK_MAX
6040 {"PC_LINK_MAX", _PC_LINK_MAX},
6041#endif
6042#ifdef _PC_MAX_CANON
6043 {"PC_MAX_CANON", _PC_MAX_CANON},
6044#endif
6045#ifdef _PC_MAX_INPUT
6046 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6047#endif
6048#ifdef _PC_NAME_MAX
6049 {"PC_NAME_MAX", _PC_NAME_MAX},
6050#endif
6051#ifdef _PC_NO_TRUNC
6052 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6053#endif
6054#ifdef _PC_PATH_MAX
6055 {"PC_PATH_MAX", _PC_PATH_MAX},
6056#endif
6057#ifdef _PC_PIPE_BUF
6058 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6059#endif
6060#ifdef _PC_PRIO_IO
6061 {"PC_PRIO_IO", _PC_PRIO_IO},
6062#endif
6063#ifdef _PC_SOCK_MAXBUF
6064 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6065#endif
6066#ifdef _PC_SYNC_IO
6067 {"PC_SYNC_IO", _PC_SYNC_IO},
6068#endif
6069#ifdef _PC_VDISABLE
6070 {"PC_VDISABLE", _PC_VDISABLE},
6071#endif
6072};
6073
Fred Drakec9680921999-12-13 16:37:25 +00006074static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006075conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006076{
6077 return conv_confname(arg, valuep, posix_constants_pathconf,
6078 sizeof(posix_constants_pathconf)
6079 / sizeof(struct constdef));
6080}
6081#endif
6082
6083#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006084PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006085"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006086Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006087If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006088
6089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006090posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006091{
6092 PyObject *result = NULL;
6093 int name, fd;
6094
Fred Drake12c6e2d1999-12-14 21:25:03 +00006095 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6096 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006097 long limit;
6098
6099 errno = 0;
6100 limit = fpathconf(fd, name);
6101 if (limit == -1 && errno != 0)
6102 posix_error();
6103 else
6104 result = PyInt_FromLong(limit);
6105 }
6106 return result;
6107}
6108#endif
6109
6110
6111#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006112PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006113"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006114Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006115If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006116
6117static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006118posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006119{
6120 PyObject *result = NULL;
6121 int name;
6122 char *path;
6123
6124 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6125 conv_path_confname, &name)) {
6126 long limit;
6127
6128 errno = 0;
6129 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006130 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006131 if (errno == EINVAL)
6132 /* could be a path or name problem */
6133 posix_error();
6134 else
6135 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006136 }
Fred Drakec9680921999-12-13 16:37:25 +00006137 else
6138 result = PyInt_FromLong(limit);
6139 }
6140 return result;
6141}
6142#endif
6143
6144#ifdef HAVE_CONFSTR
6145static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006146#ifdef _CS_ARCHITECTURE
6147 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6148#endif
6149#ifdef _CS_HOSTNAME
6150 {"CS_HOSTNAME", _CS_HOSTNAME},
6151#endif
6152#ifdef _CS_HW_PROVIDER
6153 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6154#endif
6155#ifdef _CS_HW_SERIAL
6156 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6157#endif
6158#ifdef _CS_INITTAB_NAME
6159 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6160#endif
Fred Drakec9680921999-12-13 16:37:25 +00006161#ifdef _CS_LFS64_CFLAGS
6162 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6163#endif
6164#ifdef _CS_LFS64_LDFLAGS
6165 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6166#endif
6167#ifdef _CS_LFS64_LIBS
6168 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6169#endif
6170#ifdef _CS_LFS64_LINTFLAGS
6171 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6172#endif
6173#ifdef _CS_LFS_CFLAGS
6174 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6175#endif
6176#ifdef _CS_LFS_LDFLAGS
6177 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6178#endif
6179#ifdef _CS_LFS_LIBS
6180 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6181#endif
6182#ifdef _CS_LFS_LINTFLAGS
6183 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6184#endif
Fred Draked86ed291999-12-15 15:34:33 +00006185#ifdef _CS_MACHINE
6186 {"CS_MACHINE", _CS_MACHINE},
6187#endif
Fred Drakec9680921999-12-13 16:37:25 +00006188#ifdef _CS_PATH
6189 {"CS_PATH", _CS_PATH},
6190#endif
Fred Draked86ed291999-12-15 15:34:33 +00006191#ifdef _CS_RELEASE
6192 {"CS_RELEASE", _CS_RELEASE},
6193#endif
6194#ifdef _CS_SRPC_DOMAIN
6195 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6196#endif
6197#ifdef _CS_SYSNAME
6198 {"CS_SYSNAME", _CS_SYSNAME},
6199#endif
6200#ifdef _CS_VERSION
6201 {"CS_VERSION", _CS_VERSION},
6202#endif
Fred Drakec9680921999-12-13 16:37:25 +00006203#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6204 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6205#endif
6206#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6207 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6208#endif
6209#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6210 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6211#endif
6212#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6213 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6214#endif
6215#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6216 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6217#endif
6218#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6219 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6220#endif
6221#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6222 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6223#endif
6224#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6225 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6226#endif
6227#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6228 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6229#endif
6230#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6231 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6232#endif
6233#ifdef _CS_XBS5_LP64_OFF64_LIBS
6234 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6235#endif
6236#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6237 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6238#endif
6239#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6240 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6241#endif
6242#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6243 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6244#endif
6245#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6246 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6247#endif
6248#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6249 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6250#endif
Fred Draked86ed291999-12-15 15:34:33 +00006251#ifdef _MIPS_CS_AVAIL_PROCESSORS
6252 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6253#endif
6254#ifdef _MIPS_CS_BASE
6255 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6256#endif
6257#ifdef _MIPS_CS_HOSTID
6258 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6259#endif
6260#ifdef _MIPS_CS_HW_NAME
6261 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6262#endif
6263#ifdef _MIPS_CS_NUM_PROCESSORS
6264 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6265#endif
6266#ifdef _MIPS_CS_OSREL_MAJ
6267 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6268#endif
6269#ifdef _MIPS_CS_OSREL_MIN
6270 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6271#endif
6272#ifdef _MIPS_CS_OSREL_PATCH
6273 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6274#endif
6275#ifdef _MIPS_CS_OS_NAME
6276 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6277#endif
6278#ifdef _MIPS_CS_OS_PROVIDER
6279 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6280#endif
6281#ifdef _MIPS_CS_PROCESSORS
6282 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6283#endif
6284#ifdef _MIPS_CS_SERIAL
6285 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6286#endif
6287#ifdef _MIPS_CS_VENDOR
6288 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6289#endif
Fred Drakec9680921999-12-13 16:37:25 +00006290};
6291
6292static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006293conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006294{
6295 return conv_confname(arg, valuep, posix_constants_confstr,
6296 sizeof(posix_constants_confstr)
6297 / sizeof(struct constdef));
6298}
6299
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006300PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006301"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006302Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006303
6304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006305posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006306{
6307 PyObject *result = NULL;
6308 int name;
6309 char buffer[64];
6310
6311 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6312 int len = confstr(name, buffer, sizeof(buffer));
6313
Fred Drakec9680921999-12-13 16:37:25 +00006314 errno = 0;
6315 if (len == 0) {
6316 if (errno != 0)
6317 posix_error();
6318 else
6319 result = PyString_FromString("");
6320 }
6321 else {
6322 if (len >= sizeof(buffer)) {
6323 result = PyString_FromStringAndSize(NULL, len);
6324 if (result != NULL)
6325 confstr(name, PyString_AS_STRING(result), len+1);
6326 }
6327 else
6328 result = PyString_FromString(buffer);
6329 }
6330 }
6331 return result;
6332}
6333#endif
6334
6335
6336#ifdef HAVE_SYSCONF
6337static struct constdef posix_constants_sysconf[] = {
6338#ifdef _SC_2_CHAR_TERM
6339 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6340#endif
6341#ifdef _SC_2_C_BIND
6342 {"SC_2_C_BIND", _SC_2_C_BIND},
6343#endif
6344#ifdef _SC_2_C_DEV
6345 {"SC_2_C_DEV", _SC_2_C_DEV},
6346#endif
6347#ifdef _SC_2_C_VERSION
6348 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6349#endif
6350#ifdef _SC_2_FORT_DEV
6351 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6352#endif
6353#ifdef _SC_2_FORT_RUN
6354 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6355#endif
6356#ifdef _SC_2_LOCALEDEF
6357 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6358#endif
6359#ifdef _SC_2_SW_DEV
6360 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6361#endif
6362#ifdef _SC_2_UPE
6363 {"SC_2_UPE", _SC_2_UPE},
6364#endif
6365#ifdef _SC_2_VERSION
6366 {"SC_2_VERSION", _SC_2_VERSION},
6367#endif
Fred Draked86ed291999-12-15 15:34:33 +00006368#ifdef _SC_ABI_ASYNCHRONOUS_IO
6369 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6370#endif
6371#ifdef _SC_ACL
6372 {"SC_ACL", _SC_ACL},
6373#endif
Fred Drakec9680921999-12-13 16:37:25 +00006374#ifdef _SC_AIO_LISTIO_MAX
6375 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6376#endif
Fred Drakec9680921999-12-13 16:37:25 +00006377#ifdef _SC_AIO_MAX
6378 {"SC_AIO_MAX", _SC_AIO_MAX},
6379#endif
6380#ifdef _SC_AIO_PRIO_DELTA_MAX
6381 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6382#endif
6383#ifdef _SC_ARG_MAX
6384 {"SC_ARG_MAX", _SC_ARG_MAX},
6385#endif
6386#ifdef _SC_ASYNCHRONOUS_IO
6387 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6388#endif
6389#ifdef _SC_ATEXIT_MAX
6390 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6391#endif
Fred Draked86ed291999-12-15 15:34:33 +00006392#ifdef _SC_AUDIT
6393 {"SC_AUDIT", _SC_AUDIT},
6394#endif
Fred Drakec9680921999-12-13 16:37:25 +00006395#ifdef _SC_AVPHYS_PAGES
6396 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6397#endif
6398#ifdef _SC_BC_BASE_MAX
6399 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6400#endif
6401#ifdef _SC_BC_DIM_MAX
6402 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6403#endif
6404#ifdef _SC_BC_SCALE_MAX
6405 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6406#endif
6407#ifdef _SC_BC_STRING_MAX
6408 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6409#endif
Fred Draked86ed291999-12-15 15:34:33 +00006410#ifdef _SC_CAP
6411 {"SC_CAP", _SC_CAP},
6412#endif
Fred Drakec9680921999-12-13 16:37:25 +00006413#ifdef _SC_CHARCLASS_NAME_MAX
6414 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6415#endif
6416#ifdef _SC_CHAR_BIT
6417 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6418#endif
6419#ifdef _SC_CHAR_MAX
6420 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6421#endif
6422#ifdef _SC_CHAR_MIN
6423 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6424#endif
6425#ifdef _SC_CHILD_MAX
6426 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6427#endif
6428#ifdef _SC_CLK_TCK
6429 {"SC_CLK_TCK", _SC_CLK_TCK},
6430#endif
6431#ifdef _SC_COHER_BLKSZ
6432 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6433#endif
6434#ifdef _SC_COLL_WEIGHTS_MAX
6435 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6436#endif
6437#ifdef _SC_DCACHE_ASSOC
6438 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6439#endif
6440#ifdef _SC_DCACHE_BLKSZ
6441 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6442#endif
6443#ifdef _SC_DCACHE_LINESZ
6444 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6445#endif
6446#ifdef _SC_DCACHE_SZ
6447 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6448#endif
6449#ifdef _SC_DCACHE_TBLKSZ
6450 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6451#endif
6452#ifdef _SC_DELAYTIMER_MAX
6453 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6454#endif
6455#ifdef _SC_EQUIV_CLASS_MAX
6456 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6457#endif
6458#ifdef _SC_EXPR_NEST_MAX
6459 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6460#endif
6461#ifdef _SC_FSYNC
6462 {"SC_FSYNC", _SC_FSYNC},
6463#endif
6464#ifdef _SC_GETGR_R_SIZE_MAX
6465 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6466#endif
6467#ifdef _SC_GETPW_R_SIZE_MAX
6468 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6469#endif
6470#ifdef _SC_ICACHE_ASSOC
6471 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6472#endif
6473#ifdef _SC_ICACHE_BLKSZ
6474 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6475#endif
6476#ifdef _SC_ICACHE_LINESZ
6477 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6478#endif
6479#ifdef _SC_ICACHE_SZ
6480 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6481#endif
Fred Draked86ed291999-12-15 15:34:33 +00006482#ifdef _SC_INF
6483 {"SC_INF", _SC_INF},
6484#endif
Fred Drakec9680921999-12-13 16:37:25 +00006485#ifdef _SC_INT_MAX
6486 {"SC_INT_MAX", _SC_INT_MAX},
6487#endif
6488#ifdef _SC_INT_MIN
6489 {"SC_INT_MIN", _SC_INT_MIN},
6490#endif
6491#ifdef _SC_IOV_MAX
6492 {"SC_IOV_MAX", _SC_IOV_MAX},
6493#endif
Fred Draked86ed291999-12-15 15:34:33 +00006494#ifdef _SC_IP_SECOPTS
6495 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6496#endif
Fred Drakec9680921999-12-13 16:37:25 +00006497#ifdef _SC_JOB_CONTROL
6498 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6499#endif
Fred Draked86ed291999-12-15 15:34:33 +00006500#ifdef _SC_KERN_POINTERS
6501 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6502#endif
6503#ifdef _SC_KERN_SIM
6504 {"SC_KERN_SIM", _SC_KERN_SIM},
6505#endif
Fred Drakec9680921999-12-13 16:37:25 +00006506#ifdef _SC_LINE_MAX
6507 {"SC_LINE_MAX", _SC_LINE_MAX},
6508#endif
6509#ifdef _SC_LOGIN_NAME_MAX
6510 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6511#endif
6512#ifdef _SC_LOGNAME_MAX
6513 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6514#endif
6515#ifdef _SC_LONG_BIT
6516 {"SC_LONG_BIT", _SC_LONG_BIT},
6517#endif
Fred Draked86ed291999-12-15 15:34:33 +00006518#ifdef _SC_MAC
6519 {"SC_MAC", _SC_MAC},
6520#endif
Fred Drakec9680921999-12-13 16:37:25 +00006521#ifdef _SC_MAPPED_FILES
6522 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6523#endif
6524#ifdef _SC_MAXPID
6525 {"SC_MAXPID", _SC_MAXPID},
6526#endif
6527#ifdef _SC_MB_LEN_MAX
6528 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6529#endif
6530#ifdef _SC_MEMLOCK
6531 {"SC_MEMLOCK", _SC_MEMLOCK},
6532#endif
6533#ifdef _SC_MEMLOCK_RANGE
6534 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6535#endif
6536#ifdef _SC_MEMORY_PROTECTION
6537 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6538#endif
6539#ifdef _SC_MESSAGE_PASSING
6540 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6541#endif
Fred Draked86ed291999-12-15 15:34:33 +00006542#ifdef _SC_MMAP_FIXED_ALIGNMENT
6543 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6544#endif
Fred Drakec9680921999-12-13 16:37:25 +00006545#ifdef _SC_MQ_OPEN_MAX
6546 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6547#endif
6548#ifdef _SC_MQ_PRIO_MAX
6549 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6550#endif
Fred Draked86ed291999-12-15 15:34:33 +00006551#ifdef _SC_NACLS_MAX
6552 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6553#endif
Fred Drakec9680921999-12-13 16:37:25 +00006554#ifdef _SC_NGROUPS_MAX
6555 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6556#endif
6557#ifdef _SC_NL_ARGMAX
6558 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6559#endif
6560#ifdef _SC_NL_LANGMAX
6561 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6562#endif
6563#ifdef _SC_NL_MSGMAX
6564 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6565#endif
6566#ifdef _SC_NL_NMAX
6567 {"SC_NL_NMAX", _SC_NL_NMAX},
6568#endif
6569#ifdef _SC_NL_SETMAX
6570 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6571#endif
6572#ifdef _SC_NL_TEXTMAX
6573 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6574#endif
6575#ifdef _SC_NPROCESSORS_CONF
6576 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6577#endif
6578#ifdef _SC_NPROCESSORS_ONLN
6579 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6580#endif
Fred Draked86ed291999-12-15 15:34:33 +00006581#ifdef _SC_NPROC_CONF
6582 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6583#endif
6584#ifdef _SC_NPROC_ONLN
6585 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6586#endif
Fred Drakec9680921999-12-13 16:37:25 +00006587#ifdef _SC_NZERO
6588 {"SC_NZERO", _SC_NZERO},
6589#endif
6590#ifdef _SC_OPEN_MAX
6591 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6592#endif
6593#ifdef _SC_PAGESIZE
6594 {"SC_PAGESIZE", _SC_PAGESIZE},
6595#endif
6596#ifdef _SC_PAGE_SIZE
6597 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6598#endif
6599#ifdef _SC_PASS_MAX
6600 {"SC_PASS_MAX", _SC_PASS_MAX},
6601#endif
6602#ifdef _SC_PHYS_PAGES
6603 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6604#endif
6605#ifdef _SC_PII
6606 {"SC_PII", _SC_PII},
6607#endif
6608#ifdef _SC_PII_INTERNET
6609 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6610#endif
6611#ifdef _SC_PII_INTERNET_DGRAM
6612 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6613#endif
6614#ifdef _SC_PII_INTERNET_STREAM
6615 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6616#endif
6617#ifdef _SC_PII_OSI
6618 {"SC_PII_OSI", _SC_PII_OSI},
6619#endif
6620#ifdef _SC_PII_OSI_CLTS
6621 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6622#endif
6623#ifdef _SC_PII_OSI_COTS
6624 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6625#endif
6626#ifdef _SC_PII_OSI_M
6627 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6628#endif
6629#ifdef _SC_PII_SOCKET
6630 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6631#endif
6632#ifdef _SC_PII_XTI
6633 {"SC_PII_XTI", _SC_PII_XTI},
6634#endif
6635#ifdef _SC_POLL
6636 {"SC_POLL", _SC_POLL},
6637#endif
6638#ifdef _SC_PRIORITIZED_IO
6639 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6640#endif
6641#ifdef _SC_PRIORITY_SCHEDULING
6642 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6643#endif
6644#ifdef _SC_REALTIME_SIGNALS
6645 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6646#endif
6647#ifdef _SC_RE_DUP_MAX
6648 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6649#endif
6650#ifdef _SC_RTSIG_MAX
6651 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6652#endif
6653#ifdef _SC_SAVED_IDS
6654 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6655#endif
6656#ifdef _SC_SCHAR_MAX
6657 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6658#endif
6659#ifdef _SC_SCHAR_MIN
6660 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6661#endif
6662#ifdef _SC_SELECT
6663 {"SC_SELECT", _SC_SELECT},
6664#endif
6665#ifdef _SC_SEMAPHORES
6666 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6667#endif
6668#ifdef _SC_SEM_NSEMS_MAX
6669 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6670#endif
6671#ifdef _SC_SEM_VALUE_MAX
6672 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6673#endif
6674#ifdef _SC_SHARED_MEMORY_OBJECTS
6675 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6676#endif
6677#ifdef _SC_SHRT_MAX
6678 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6679#endif
6680#ifdef _SC_SHRT_MIN
6681 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6682#endif
6683#ifdef _SC_SIGQUEUE_MAX
6684 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6685#endif
6686#ifdef _SC_SIGRT_MAX
6687 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6688#endif
6689#ifdef _SC_SIGRT_MIN
6690 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6691#endif
Fred Draked86ed291999-12-15 15:34:33 +00006692#ifdef _SC_SOFTPOWER
6693 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6694#endif
Fred Drakec9680921999-12-13 16:37:25 +00006695#ifdef _SC_SPLIT_CACHE
6696 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6697#endif
6698#ifdef _SC_SSIZE_MAX
6699 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6700#endif
6701#ifdef _SC_STACK_PROT
6702 {"SC_STACK_PROT", _SC_STACK_PROT},
6703#endif
6704#ifdef _SC_STREAM_MAX
6705 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6706#endif
6707#ifdef _SC_SYNCHRONIZED_IO
6708 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6709#endif
6710#ifdef _SC_THREADS
6711 {"SC_THREADS", _SC_THREADS},
6712#endif
6713#ifdef _SC_THREAD_ATTR_STACKADDR
6714 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6715#endif
6716#ifdef _SC_THREAD_ATTR_STACKSIZE
6717 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6718#endif
6719#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6720 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6721#endif
6722#ifdef _SC_THREAD_KEYS_MAX
6723 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6724#endif
6725#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6726 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6727#endif
6728#ifdef _SC_THREAD_PRIO_INHERIT
6729 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6730#endif
6731#ifdef _SC_THREAD_PRIO_PROTECT
6732 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6733#endif
6734#ifdef _SC_THREAD_PROCESS_SHARED
6735 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6736#endif
6737#ifdef _SC_THREAD_SAFE_FUNCTIONS
6738 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6739#endif
6740#ifdef _SC_THREAD_STACK_MIN
6741 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6742#endif
6743#ifdef _SC_THREAD_THREADS_MAX
6744 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6745#endif
6746#ifdef _SC_TIMERS
6747 {"SC_TIMERS", _SC_TIMERS},
6748#endif
6749#ifdef _SC_TIMER_MAX
6750 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6751#endif
6752#ifdef _SC_TTY_NAME_MAX
6753 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6754#endif
6755#ifdef _SC_TZNAME_MAX
6756 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6757#endif
6758#ifdef _SC_T_IOV_MAX
6759 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6760#endif
6761#ifdef _SC_UCHAR_MAX
6762 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6763#endif
6764#ifdef _SC_UINT_MAX
6765 {"SC_UINT_MAX", _SC_UINT_MAX},
6766#endif
6767#ifdef _SC_UIO_MAXIOV
6768 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6769#endif
6770#ifdef _SC_ULONG_MAX
6771 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6772#endif
6773#ifdef _SC_USHRT_MAX
6774 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6775#endif
6776#ifdef _SC_VERSION
6777 {"SC_VERSION", _SC_VERSION},
6778#endif
6779#ifdef _SC_WORD_BIT
6780 {"SC_WORD_BIT", _SC_WORD_BIT},
6781#endif
6782#ifdef _SC_XBS5_ILP32_OFF32
6783 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6784#endif
6785#ifdef _SC_XBS5_ILP32_OFFBIG
6786 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6787#endif
6788#ifdef _SC_XBS5_LP64_OFF64
6789 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
6790#endif
6791#ifdef _SC_XBS5_LPBIG_OFFBIG
6792 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
6793#endif
6794#ifdef _SC_XOPEN_CRYPT
6795 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
6796#endif
6797#ifdef _SC_XOPEN_ENH_I18N
6798 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
6799#endif
6800#ifdef _SC_XOPEN_LEGACY
6801 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
6802#endif
6803#ifdef _SC_XOPEN_REALTIME
6804 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
6805#endif
6806#ifdef _SC_XOPEN_REALTIME_THREADS
6807 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
6808#endif
6809#ifdef _SC_XOPEN_SHM
6810 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
6811#endif
6812#ifdef _SC_XOPEN_UNIX
6813 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
6814#endif
6815#ifdef _SC_XOPEN_VERSION
6816 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
6817#endif
6818#ifdef _SC_XOPEN_XCU_VERSION
6819 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
6820#endif
6821#ifdef _SC_XOPEN_XPG2
6822 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
6823#endif
6824#ifdef _SC_XOPEN_XPG3
6825 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
6826#endif
6827#ifdef _SC_XOPEN_XPG4
6828 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
6829#endif
6830};
6831
6832static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006833conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006834{
6835 return conv_confname(arg, valuep, posix_constants_sysconf,
6836 sizeof(posix_constants_sysconf)
6837 / sizeof(struct constdef));
6838}
6839
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006840PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006841"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006842Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006843
6844static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006845posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006846{
6847 PyObject *result = NULL;
6848 int name;
6849
6850 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
6851 int value;
6852
6853 errno = 0;
6854 value = sysconf(name);
6855 if (value == -1 && errno != 0)
6856 posix_error();
6857 else
6858 result = PyInt_FromLong(value);
6859 }
6860 return result;
6861}
6862#endif
6863
6864
Fred Drakebec628d1999-12-15 18:31:10 +00006865/* This code is used to ensure that the tables of configuration value names
6866 * are in sorted order as required by conv_confname(), and also to build the
6867 * the exported dictionaries that are used to publish information about the
6868 * names available on the host platform.
6869 *
6870 * Sorting the table at runtime ensures that the table is properly ordered
6871 * when used, even for platforms we're not able to test on. It also makes
6872 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00006873 */
Fred Drakebec628d1999-12-15 18:31:10 +00006874
6875static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006876cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00006877{
6878 const struct constdef *c1 =
6879 (const struct constdef *) v1;
6880 const struct constdef *c2 =
6881 (const struct constdef *) v2;
6882
6883 return strcmp(c1->name, c2->name);
6884}
6885
6886static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006887setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00006888 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006889{
Fred Drakebec628d1999-12-15 18:31:10 +00006890 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00006891 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00006892
6893 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
6894 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00006895 if (d == NULL)
6896 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006897
Barry Warsaw3155db32000-04-13 15:20:40 +00006898 for (i=0; i < tablesize; ++i) {
6899 PyObject *o = PyInt_FromLong(table[i].value);
6900 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
6901 Py_XDECREF(o);
6902 Py_DECREF(d);
6903 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006904 }
Barry Warsaw3155db32000-04-13 15:20:40 +00006905 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00006906 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00006907 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00006908}
6909
Fred Drakebec628d1999-12-15 18:31:10 +00006910/* Return -1 on failure, 0 on success. */
6911static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00006912setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00006913{
6914#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00006915 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00006916 sizeof(posix_constants_pathconf)
6917 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006918 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006919 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006920#endif
6921#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00006922 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00006923 sizeof(posix_constants_confstr)
6924 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006925 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006926 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006927#endif
6928#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00006929 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00006930 sizeof(posix_constants_sysconf)
6931 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00006932 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00006933 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00006934#endif
Fred Drakebec628d1999-12-15 18:31:10 +00006935 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00006936}
Fred Draked86ed291999-12-15 15:34:33 +00006937
6938
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006939PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006940"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006941Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006942in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006943
6944static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006945posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006946{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006947 abort();
6948 /*NOTREACHED*/
6949 Py_FatalError("abort() called from Python code didn't abort!");
6950 return NULL;
6951}
Fred Drakebec628d1999-12-15 18:31:10 +00006952
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006953#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006954PyDoc_STRVAR(win32_startfile__doc__,
6955"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00006956\n\
6957This acts like double-clicking the file in Explorer, or giving the file\n\
6958name as an argument to the DOS \"start\" command: the file is opened\n\
6959with whatever application (if any) its extension is associated.\n\
6960\n\
6961startfile returns as soon as the associated application is launched.\n\
6962There is no option to wait for the application to close, and no way\n\
6963to retrieve the application's exit status.\n\
6964\n\
6965The filepath is relative to the current directory. If you want to use\n\
6966an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006967the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00006968
6969static PyObject *
6970win32_startfile(PyObject *self, PyObject *args)
6971{
6972 char *filepath;
6973 HINSTANCE rc;
6974 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
6975 return NULL;
6976 Py_BEGIN_ALLOW_THREADS
6977 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
6978 Py_END_ALLOW_THREADS
6979 if (rc <= (HINSTANCE)32)
6980 return win32_error("startfile", filepath);
6981 Py_INCREF(Py_None);
6982 return Py_None;
6983}
6984#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006985
Martin v. Löwis438b5342002-12-27 10:16:42 +00006986#ifdef HAVE_GETLOADAVG
6987PyDoc_STRVAR(posix_getloadavg__doc__,
6988"getloadavg() -> (float, float, float)\n\n\
6989Return the number of processes in the system run queue averaged over\n\
6990the last 1, 5, and 15 minutes or raises OSError if the load average\n\
6991was unobtainable");
6992
6993static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006994posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00006995{
6996 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00006997 if (getloadavg(loadavg, 3)!=3) {
6998 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
6999 return NULL;
7000 } else
7001 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7002}
7003#endif
7004
7005
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007006static PyMethodDef posix_methods[] = {
7007 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7008#ifdef HAVE_TTYNAME
7009 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7010#endif
7011 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7012 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007013#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007014 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007015#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007016#ifdef HAVE_LCHOWN
7017 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7018#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007019#ifdef HAVE_CHROOT
7020 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7021#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007022#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007023 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007024#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007025#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007026 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007027#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007028 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007029#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007030#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007031#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007032 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007033#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007034 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7035 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7036 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007037#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007038 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007039#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007040#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007041 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007042#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007043 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7044 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7045 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007046 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007047#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007048 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007049#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007050#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007051 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007052#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007053 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007054#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007055 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007056#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007057 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7058 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7059 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007060#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007061 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007062#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007063 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007064#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007065 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7066 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007067#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007068#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007069 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7070 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Guido van Rossuma1065681999-01-25 23:20:23 +00007071#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007072#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007073 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007074#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007075#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007076 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007077#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007078#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007079 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007080#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007081#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007082 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007083#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007084#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007085 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007086#endif /* HAVE_GETEGID */
7087#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007088 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007089#endif /* HAVE_GETEUID */
7090#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007091 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007092#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007093#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007094 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007095#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007096 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007097#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007098 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007099#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007100#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007101 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007102#endif /* HAVE_GETPPID */
7103#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007104 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007105#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007106#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007107 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007108#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007109#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007110 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007111#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007112#ifdef HAVE_KILLPG
7113 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7114#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007115#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007116 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007117#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007118#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007119 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007120#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007121 {"popen2", win32_popen2, METH_VARARGS},
7122 {"popen3", win32_popen3, METH_VARARGS},
7123 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007124 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007125#else
7126#if defined(PYOS_OS2) && defined(PYCC_GCC)
7127 {"popen2", os2emx_popen2, METH_VARARGS},
7128 {"popen3", os2emx_popen3, METH_VARARGS},
7129 {"popen4", os2emx_popen4, METH_VARARGS},
7130#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007131#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007132#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007133#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007134 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007135#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007136#ifdef HAVE_SETEUID
7137 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7138#endif /* HAVE_SETEUID */
7139#ifdef HAVE_SETEGID
7140 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7141#endif /* HAVE_SETEGID */
7142#ifdef HAVE_SETREUID
7143 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7144#endif /* HAVE_SETREUID */
7145#ifdef HAVE_SETREGID
7146 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7147#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007148#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007149 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007150#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007151#ifdef HAVE_SETGROUPS
7152 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7153#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007154#ifdef HAVE_GETPGID
7155 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7156#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007157#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007158 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007159#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007160#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007161 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007162#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007163#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007164 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007165#endif /* HAVE_WAITPID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007166#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007167 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007168#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007169#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007170 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007171#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007172#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007173 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007174#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007175#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007176 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007177#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007178 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7179 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7180 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7181 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7182 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7183 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7184 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7185 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7186 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007187 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007188#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007189 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007190#endif
7191#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007192 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007193#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007194#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007195 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7196#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007197#ifdef HAVE_DEVICE_MACROS
7198 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7199 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7200 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7201#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007202#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007203 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007204#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007205#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007206 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007207#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007208#ifdef HAVE_UNSETENV
7209 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7210#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007211#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007212 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007213#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007214#ifdef HAVE_FCHDIR
7215 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7216#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007217#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007218 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007219#endif
7220#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007221 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007222#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007223#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007224#ifdef WCOREDUMP
7225 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7226#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007227#ifdef WIFCONTINUED
7228 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7229#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007230#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007231 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007232#endif /* WIFSTOPPED */
7233#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007234 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007235#endif /* WIFSIGNALED */
7236#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007237 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007238#endif /* WIFEXITED */
7239#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007240 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007241#endif /* WEXITSTATUS */
7242#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007243 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007244#endif /* WTERMSIG */
7245#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007246 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007247#endif /* WSTOPSIG */
7248#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007249#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007250 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007251#endif
7252#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007253 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007254#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007255#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007256 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007257#endif
7258#ifdef HAVE_TEMPNAM
7259 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7260#endif
7261#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007262 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007263#endif
Fred Drakec9680921999-12-13 16:37:25 +00007264#ifdef HAVE_CONFSTR
7265 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7266#endif
7267#ifdef HAVE_SYSCONF
7268 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7269#endif
7270#ifdef HAVE_FPATHCONF
7271 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7272#endif
7273#ifdef HAVE_PATHCONF
7274 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7275#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007276 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007277#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007278 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7279#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007280#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007281 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007282#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007283 {NULL, NULL} /* Sentinel */
7284};
7285
7286
Barry Warsaw4a342091996-12-19 23:50:02 +00007287static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007288ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007289{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007290 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007291}
7292
Guido van Rossumd48f2521997-12-05 22:19:34 +00007293#if defined(PYOS_OS2)
7294/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007295static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007296{
7297 APIRET rc;
7298 ULONG values[QSV_MAX+1];
7299 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007300 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007301
7302 Py_BEGIN_ALLOW_THREADS
7303 rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
7304 Py_END_ALLOW_THREADS
7305
7306 if (rc != NO_ERROR) {
7307 os2_error(rc);
7308 return -1;
7309 }
7310
Fred Drake4d1e64b2002-04-15 19:40:07 +00007311 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7312 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7313 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7314 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7315 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7316 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7317 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007318
7319 switch (values[QSV_VERSION_MINOR]) {
7320 case 0: ver = "2.00"; break;
7321 case 10: ver = "2.10"; break;
7322 case 11: ver = "2.11"; break;
7323 case 30: ver = "3.00"; break;
7324 case 40: ver = "4.00"; break;
7325 case 50: ver = "5.00"; break;
7326 default:
Tim Peters885d4572001-11-28 20:27:42 +00007327 PyOS_snprintf(tmp, sizeof(tmp),
7328 "%d-%d", values[QSV_VERSION_MAJOR],
7329 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007330 ver = &tmp[0];
7331 }
7332
7333 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007334 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007335 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007336
7337 /* Add Indicator of Which Drive was Used to Boot the System */
7338 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7339 tmp[1] = ':';
7340 tmp[2] = '\0';
7341
Fred Drake4d1e64b2002-04-15 19:40:07 +00007342 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007343}
7344#endif
7345
Barry Warsaw4a342091996-12-19 23:50:02 +00007346static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007347all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007348{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007349#ifdef F_OK
7350 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007351#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007352#ifdef R_OK
7353 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007354#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007355#ifdef W_OK
7356 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007357#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007358#ifdef X_OK
7359 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007360#endif
Fred Drakec9680921999-12-13 16:37:25 +00007361#ifdef NGROUPS_MAX
7362 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7363#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007364#ifdef TMP_MAX
7365 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7366#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007367#ifdef WCONTINUED
7368 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7369#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007370#ifdef WNOHANG
7371 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007372#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007373#ifdef WUNTRACED
7374 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7375#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007376#ifdef O_RDONLY
7377 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7378#endif
7379#ifdef O_WRONLY
7380 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7381#endif
7382#ifdef O_RDWR
7383 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7384#endif
7385#ifdef O_NDELAY
7386 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7387#endif
7388#ifdef O_NONBLOCK
7389 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7390#endif
7391#ifdef O_APPEND
7392 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7393#endif
7394#ifdef O_DSYNC
7395 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7396#endif
7397#ifdef O_RSYNC
7398 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7399#endif
7400#ifdef O_SYNC
7401 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7402#endif
7403#ifdef O_NOCTTY
7404 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7405#endif
7406#ifdef O_CREAT
7407 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7408#endif
7409#ifdef O_EXCL
7410 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7411#endif
7412#ifdef O_TRUNC
7413 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7414#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007415#ifdef O_BINARY
7416 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7417#endif
7418#ifdef O_TEXT
7419 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7420#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007421#ifdef O_LARGEFILE
7422 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7423#endif
7424
Tim Peters5aa91602002-01-30 05:46:57 +00007425/* MS Windows */
7426#ifdef O_NOINHERIT
7427 /* Don't inherit in child processes. */
7428 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7429#endif
7430#ifdef _O_SHORT_LIVED
7431 /* Optimize for short life (keep in memory). */
7432 /* MS forgot to define this one with a non-underscore form too. */
7433 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7434#endif
7435#ifdef O_TEMPORARY
7436 /* Automatically delete when last handle is closed. */
7437 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7438#endif
7439#ifdef O_RANDOM
7440 /* Optimize for random access. */
7441 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7442#endif
7443#ifdef O_SEQUENTIAL
7444 /* Optimize for sequential access. */
7445 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7446#endif
7447
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007448/* GNU extensions. */
7449#ifdef O_DIRECT
7450 /* Direct disk access. */
7451 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7452#endif
7453#ifdef O_DIRECTORY
7454 /* Must be a directory. */
7455 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7456#endif
7457#ifdef O_NOFOLLOW
7458 /* Do not follow links. */
7459 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7460#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007461
Barry Warsaw5676bd12003-01-07 20:57:09 +00007462 /* These come from sysexits.h */
7463#ifdef EX_OK
7464 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007465#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007466#ifdef EX_USAGE
7467 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007468#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007469#ifdef EX_DATAERR
7470 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007471#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007472#ifdef EX_NOINPUT
7473 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007474#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007475#ifdef EX_NOUSER
7476 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007477#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007478#ifdef EX_NOHOST
7479 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007480#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007481#ifdef EX_UNAVAILABLE
7482 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007483#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007484#ifdef EX_SOFTWARE
7485 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007486#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007487#ifdef EX_OSERR
7488 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007489#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007490#ifdef EX_OSFILE
7491 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007492#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007493#ifdef EX_CANTCREAT
7494 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007495#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007496#ifdef EX_IOERR
7497 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007498#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007499#ifdef EX_TEMPFAIL
7500 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007501#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007502#ifdef EX_PROTOCOL
7503 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007504#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007505#ifdef EX_NOPERM
7506 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007507#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007508#ifdef EX_CONFIG
7509 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007510#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007511#ifdef EX_NOTFOUND
7512 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007513#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007514
Guido van Rossum246bc171999-02-01 23:54:31 +00007515#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007516#if defined(PYOS_OS2) && defined(PYCC_GCC)
7517 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7518 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7519 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7520 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7521 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7522 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7523 if (ins(d, "P_PM", (long)P_PM)) return -1;
7524 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7525 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7526 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7527 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7528 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7529 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7530 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7531 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7532 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7533 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7534 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7535 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7536 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7537#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007538 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7539 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7540 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7541 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7542 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007543#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007544#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007545
Guido van Rossumd48f2521997-12-05 22:19:34 +00007546#if defined(PYOS_OS2)
7547 if (insertvalues(d)) return -1;
7548#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007549 return 0;
7550}
7551
7552
Tim Peters5aa91602002-01-30 05:46:57 +00007553#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007554#define INITFUNC initnt
7555#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007556
7557#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007558#define INITFUNC initos2
7559#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007560
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007561#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007562#define INITFUNC initposix
7563#define MODNAME "posix"
7564#endif
7565
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007566PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007567INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007568{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007569 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007570
Fred Drake4d1e64b2002-04-15 19:40:07 +00007571 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007572 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007573 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007574
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007575 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007576 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007577 Py_XINCREF(v);
7578 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007579 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007580 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007581
Fred Drake4d1e64b2002-04-15 19:40:07 +00007582 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007583 return;
7584
Fred Drake4d1e64b2002-04-15 19:40:07 +00007585 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007586 return;
7587
Fred Drake4d1e64b2002-04-15 19:40:07 +00007588 Py_INCREF(PyExc_OSError);
7589 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007590
Guido van Rossumb3d39562000-01-31 18:41:26 +00007591#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007592 if (posix_putenv_garbage == NULL)
7593 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007594#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007595
Guido van Rossum14648392001-12-08 18:02:58 +00007596 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007597 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7598 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7599 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007600 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007601 structseq_new = StatResultType.tp_new;
7602 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007603 Py_INCREF((PyObject*) &StatResultType);
7604 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007605
Guido van Rossum14648392001-12-08 18:02:58 +00007606 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007607 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007608 Py_INCREF((PyObject*) &StatVFSResultType);
7609 PyModule_AddObject(m, "statvfs_result",
7610 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007611}